Skip to content

Conversation

@melizeche
Copy link
Member

Details

Fix broke CI


Checklist

  • Local tests pass (ak test authentik/)
  • The code has been formatted (make lint-fix)

If an API change has been made

  • The API schema has been updated (make gen-build)

If changes to the frontend have been made

  • The code has been formatted (make web)

If applicable

  • The documentation has been updated
  • The documentation has been formatted (make website)

@melizeche melizeche requested a review from a team as a code owner March 24, 2025 19:01
@netlify
Copy link

netlify bot commented Mar 24, 2025

Deploy Preview for authentik-docs canceled.

Name Link
🔨 Latest commit 2223d71
🔍 Latest deploy log https://app.netlify.com/sites/authentik-docs/deploys/67e1b34c8c0719000855776b

@melizeche melizeche changed the title core: use uv instead of poetry in test-migrations-from-stable infrastructure: use uv instead of poetry in test-migrations-from-stable Mar 24, 2025
@netlify
Copy link

netlify bot commented Mar 24, 2025

Deploy Preview for authentik-storybook canceled.

Name Link
🔨 Latest commit 2223d71
🔍 Latest deploy log https://app.netlify.com/sites/authentik-storybook/deploys/67e1b34c9f03680008c101dc

@melizeche melizeche requested a review from a team as a code owner March 24, 2025 19:12
Copy link
Member

@rissson rissson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect. This poetry run is run from the 2025.2.2 tag, which is still poetry, and thus correct. See #13538

@codecov
Copy link

codecov bot commented Mar 24, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
1725 2 1723 2
View the top 2 failed test(s) by shortest run time
authentik.events.tests.test_api.TestEventsAPI::test_filter_model_pk_int
Stack Traces | 0.54s run time
self = <unittest.case._Outcome object at 0x7f7f7bf1e660>
test_case = <authentik.events.tests.test_api.TestEventsAPI testMethod=test_filter_model_pk_int>
subTest = False

    @contextlib.contextmanager
    def testPartExecutor(self, test_case, subTest=False):
        old_success = self.success
        self.success = True
        try:
>           yield

.../hostedtoolcache/Python/3.12.9........./x64/lib/python3.12/unittest/case.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.events.tests.test_api.TestEventsAPI testMethod=test_filter_model_pk_int>
result = <TestCaseFunction test_filter_model_pk_int>

    def run(self, result=None):
        if result is None:
            result = self.defaultTestResult()
            startTestRun = getattr(result, 'startTestRun', None)
            stopTestRun = getattr(result, 'stopTestRun', None)
            if startTestRun is not None:
                startTestRun()
        else:
            stopTestRun = None
    
        result.startTest(self)
        try:
            testMethod = getattr(self, self._testMethodName)
            if (getattr(self.__class__, "__unittest_skip__", False) or
                getattr(testMethod, "__unittest_skip__", False)):
                # If the class or method was skipped.
                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
                            or getattr(testMethod, '__unittest_skip_why__', ''))
                _addSkip(result, self, skip_why)
                return result
    
            expecting_failure = (
                getattr(self, "__unittest_expecting_failure__", False) or
                getattr(testMethod, "__unittest_expecting_failure__", False)
            )
            outcome = _Outcome(result)
            start_time = time.perf_counter()
            try:
                self._outcome = outcome
    
                with outcome.testPartExecutor(self):
                    self._callSetUp()
                if outcome.success:
                    outcome.expecting_failure = expecting_failure
                    with outcome.testPartExecutor(self):
>                       self._callTestMethod(testMethod)

.../hostedtoolcache/Python/3.12.9........./x64/lib/python3.12/unittest/case.py:634: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.events.tests.test_api.TestEventsAPI testMethod=test_filter_model_pk_int>
method = <bound method TestEventsAPI.test_filter_model_pk_int of <authentik.events.tests.test_api.TestEventsAPI testMethod=test_filter_model_pk_int>>

    def _callTestMethod(self, method):
>       if method() is not None:

.../hostedtoolcache/Python/3.12.9........./x64/lib/python3.12/unittest/case.py:589: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.events.tests.test_api.TestEventsAPI testMethod=test_filter_model_pk_int>

    def test_filter_model_pk_int(self):
        """Test event list with context_model_pk and integer PKs"""
        provider = OAuth2Provider.objects.create(
            name=generate_id(),
        )
        event = Event.new(EventAction.MODEL_CREATED, model=model_to_dict(provider))
        event.save()
>       response = self.client.get(
            reverse("authentik_api:event-list"),
            data={
                "context_model_pk": provider.pk,
                "context_model_app": "authentik_providers_oauth2",
                "context_model_name": "oauth2provider",
            },
        )

.../events/tests/test_api.py:35: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f7f70974680>
path = '.../v3/events/events/'
data = {'context_model_app': 'authentik_providers_oauth2', 'context_model_name': 'oauth2provider', 'context_model_pk': 24}
follow = False, extra = {}

    def get(self, path, data=None, follow=False, **extra):
>       response = super().get(path, data=data, **extra)

.venv/lib/python3.12.............../site-packages/rest_framework/test.py:289: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f7f70974680>
path = '.../v3/events/events/'
data = {'context_model_app': 'authentik_providers_oauth2', 'context_model_name': 'oauth2provider', 'context_model_pk': 24}
extra = {}
r = {'QUERY_STRING': 'context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'}

    def get(self, path, data=None, **extra):
        r = {
            'QUERY_STRING': urlencode(data or {}, doseq=True),
        }
        if not data and '?' in path:
            # Fix to support old behavior where you have the arguments in the
            # url. See #1461.
            query_string = force_bytes(path.split('?')[1])
            query_string = query_string.decode('iso-8859-1')
            r['QUERY_STRING'] = query_string
        r.update(extra)
>       return self.generic('GET', path, **r)

.venv/lib/python3.12.............../site-packages/rest_framework/test.py:206: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f7f70974680>, method = 'GET'
path = '.../v3/events/events/', data = ''
content_type = 'application/octet-stream', secure = False
extra = {'CONTENT_TYPE': 'application/octet-stream', 'QUERY_STRING': 'context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'}

    def generic(self, method, path, data='',
                content_type='application/octet-stream', secure=False, **extra):
        # Include the CONTENT_TYPE, regardless of whether or not data is empty.
        if content_type is not None:
            extra['CONTENT_TYPE'] = str(content_type)
    
>       return super().generic(
            method, path, data, content_type, secure, **extra)

.venv/lib/python3.12.............../site-packages/rest_framework/test.py:234: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f7f70974680>, method = 'GET'
path = '.../v3/events/events/', data = b''
content_type = 'application/octet-stream', secure = False, headers = None
query_params = None
extra = {'CONTENT_TYPE': 'application/octet-stream', 'QUERY_STRING': 'context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'}
parsed = ParseResult(scheme='', netloc='', path='.../v3/events/events/', params='', query='', fragment='')
r = {'CONTENT_TYPE': 'application/octet-stream', 'PATH_INFO': '.../v3/events/events/', 'QUERY_STRING': 'context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider', 'REQUEST_METHOD': 'GET', ...}

    def generic(
        self,
        method,
        path,
        data="",
        content_type="application/octet-stream",
        secure=False,
        *,
        headers=None,
        query_params=None,
        **extra,
    ):
        """Construct an arbitrary HTTP request."""
        parsed = urlparse(str(path))  # path can be lazy
        data = force_bytes(data, settings.DEFAULT_CHARSET)
        r = {
            "PATH_INFO": self._get_path(parsed),
            "REQUEST_METHOD": method,
            "SERVER_PORT": "443" if secure else "80",
            "wsgi.url_scheme": "https" if secure else "http",
        }
        if data:
            r.update(
                {
                    "CONTENT_LENGTH": str(len(data)),
                    "CONTENT_TYPE": content_type,
                    "wsgi.input": FakePayload(data),
                }
            )
        if headers:
            extra.update(HttpHeaders.to_wsgi_names(headers))
        if query_params:
            extra["QUERY_STRING"] = urlencode(query_params, doseq=True)
        r.update(extra)
        # If QUERY_STRING is absent or empty, we want to extract it from the URL.
        if not r.get("QUERY_STRING"):
            # WSGI requires latin-1 encoded strings. See get_path_info().
            query_string = parsed[4].encode().decode("iso-8859-1")
            r["QUERY_STRING"] = query_string
>       return self.request(**r)

.venv/lib/python3.12.../django/test/client.py:676: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f7f70974680>
kwargs = {'CONTENT_TYPE': 'application/octet-stream', 'PATH_INFO': '.../v3/events/events/', 'QUERY_STRING': 'context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider', 'REQUEST_METHOD': 'GET', ...}

    def request(self, **kwargs):
        # Ensure that any credentials set get added to every request.
        kwargs.update(self._credentials)
>       return super().request(**kwargs)

.venv/lib/python3.12.............../site-packages/rest_framework/test.py:286: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f7f70974680>
kwargs = {'CONTENT_TYPE': 'application/octet-stream', 'PATH_INFO': '.../v3/events/events/', 'QUERY_STRING': 'context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider', 'REQUEST_METHOD': 'GET', ...}

    def request(self, **kwargs):
>       request = super().request(**kwargs)

.venv/lib/python3.12.............../site-packages/rest_framework/test.py:238: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f7f70974680>
request = {'CONTENT_TYPE': 'application/octet-stream', 'PATH_INFO': '.../v3/events/events/', 'QUERY_STRING': 'context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider', 'REQUEST_METHOD': 'GET', ...}
environ = {'CONTENT_TYPE': 'application/octet-stream', 'HTTP_COOKIE': 'authentik_session=5jnplfhtnqfpigggxqzkmraq4gz8gfjd', 'PAT...ERY_STRING': 'context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider', ...}
data = {'context': [[{'True': True, 'False': False, 'None': None}, {'csrf_token': <SimpleLazyObject: <function csrf.<locals>....se/ske...">, <Template template_string="{% load static %}{%...">, <Template template_string="{% load i18n %}{% g...">]}
on_template_render = functools.partial(<function store_rendered_templates at 0x7f7f7d57d120>, {'templates': [<Template template_string="{% ...<IncludeNode: template=<FilterExpression '"base/header_js.html"'>>, <TextNode: '\n'>]>}, {'LANGUAGE_CODE': 'en-us'}]]})
signal_uid = 'template-render-140185355850816'
exception_uid = 'request-exception-140185355850816'
response = <ServerErrorTemplateResponse status_code=500, "text/html; charset=utf-8">

    def request(self, **request):
        """
        Make a generic request. Compose the environment dictionary and pass
        to the handler, return the result of the handler. Assume defaults for
        the query environment, which can be overridden using the arguments to
        the request.
        """
        environ = self._base_environ(**request)
    
        # Curry a data dictionary into an instance of the template renderer
        # callback function.
        data = {}
        on_template_render = partial(store_rendered_templates, data)
        signal_uid = "template-render-%s" % id(request)
        signals.template_rendered.connect(on_template_render, dispatch_uid=signal_uid)
        # Capture exceptions created by the handler.
        exception_uid = "request-exception-%s" % id(request)
        got_request_exception.connect(self.store_exc_info, dispatch_uid=exception_uid)
        try:
            response = self.handler(environ)
        finally:
            signals.template_rendered.disconnect(dispatch_uid=signal_uid)
            got_request_exception.disconnect(dispatch_uid=exception_uid)
        # Check for signaled exceptions.
>       self.check_exception(response)

.venv/lib/python3.12.../django/test/client.py:1092: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f7f70974680>
response = <ServerErrorTemplateResponse status_code=500, "text/html; charset=utf-8">

    def check_exception(self, response):
        """
        Look for a signaled exception, clear the current context exception
        data, re-raise the signaled exception, and clear the signaled exception
        from the local cache.
        """
        response.exc_info = self.exc_info
        if self.exc_info:
            _, exc_value, _ = self.exc_info
            self.exc_info = None
            if self.raise_request_exception:
>               raise exc_value

.venv/lib/python3.12.../django/test/client.py:805: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

request = <WSGIRequest: GET '.../v3/events/events/?context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'>

    @wraps(get_response)
    def inner(request):
        try:
>           response = get_response(request)

.venv/lib/python3.12.../core/handlers/exception.py:55: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.ForceAuthClientHandler object at 0x7f7f72f40050>
request = <WSGIRequest: GET '.../v3/events/events/?context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'>

    def _get_response(self, request):
        """
        Resolve and call the view, then apply view, exception, and
        template_response middleware. This method is everything that happens
        inside the request/response middleware.
        """
        response = None
        callback, callback_args, callback_kwargs = self.resolve_request(request)
    
        # Apply view middleware
        for middleware_method in self._view_middleware:
            response = middleware_method(
                request, callback, callback_args, callback_kwargs
            )
            if response:
                break
    
        if response is None:
            wrapped_callback = self.make_view_atomic(callback)
            # If it is an asynchronous view, run it in a subthread.
            if iscoroutinefunction(wrapped_callback):
                wrapped_callback = async_to_sync(wrapped_callback)
            try:
>               response = wrapped_callback(request, *callback_args, **callback_kwargs)

.venv/lib/python3.12.../core/handlers/base.py:197: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

request = <WSGIRequest: GET '.../v3/events/events/?context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'>
args = (), kwargs = {}
current_scope = <Scope id=0x7f7f7fdf1fc0 name=None type=ScopeType.CURRENT>
sentry_scope = <Scope id=0x7f7f808d3a00 name=None type=ScopeType.ISOLATION>

    @functools.wraps(callback)
    def sentry_wrapped_callback(request, *args, **kwargs):
        # type: (Any, *Any, **Any) -> Any
        current_scope = sentry_sdk.get_current_scope()
        if current_scope.transaction is not None:
            current_scope.transaction.update_active_thread()
    
        sentry_scope = sentry_sdk.get_isolation_scope()
        # set the active thread id to the handler thread for sync views
        # this isn't necessary for async views since that runs on main
        if sentry_scope.profile is not None:
            sentry_scope.profile.update_active_thread_id()
    
        with sentry_sdk.start_span(
            op=OP.VIEW_RENDER,
            name=request.resolver_match.view_name,
            origin=DjangoIntegration.origin,
        ):
>           return callback(request, *args, **kwargs)

.venv/lib/python3.12.../integrations/django/views.py:94: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

request = <WSGIRequest: GET '.../v3/events/events/?context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'>
args = (), kwargs = {}

    def _view_wrapper(request, *args, **kwargs):
>       return view_func(request, *args, **kwargs)

.venv/lib/python3.12.../views/decorators/csrf.py:65: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

request = <WSGIRequest: GET '.../v3/events/events/?context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'>
args = (), kwargs = {}
self = <authentik.events.api.events.EventViewSet object at 0x7f7f7289ecc0>
method = 'head', action = 'list'
handler = <bound method ListModelMixin.list of <authentik.events.api.events.EventViewSet object at 0x7f7f7289ecc0>>

    def view(request, *args, **kwargs):
        self = cls(**initkwargs)
    
        if 'get' in actions and 'head' not in actions:
            actions['head'] = actions['get']
    
        # We also store the mapping of request methods to actions,
        # so that we can later set the action attribute.
        # eg. `self.action = 'list'` on an incoming GET request.
        self.action_map = actions
    
        # Bind methods to actions
        # This is the bit that's different to a standard view
        for method, action in actions.items():
            handler = getattr(self, action)
            setattr(self, method, handler)
    
        self.request = request
        self.args = args
        self.kwargs = kwargs
    
        # And continue as usual
>       return self.dispatch(request, *args, **kwargs)

.venv/lib/python3.12.../site-packages/rest_framework/viewsets.py:125: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.events.api.events.EventViewSet object at 0x7f7f7289ecc0>
request = <rest_framework.request.Request: GET '.../v3/events/events/?context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'>
args = (), kwargs = {}
handler = <bound method ListModelMixin.list of <authentik.events.api.events.EventViewSet object at 0x7f7f7289ecc0>>

    def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?
    
        try:
            self.initial(request, *args, **kwargs)
    
            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
    
            response = handler(request, *args, **kwargs)
    
        except Exception as exc:
>           response = self.handle_exception(exc)

.venv/lib/python3.12............/site-packages/rest_framework/views.py:509: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.events.api.events.EventViewSet object at 0x7f7f7289ecc0>
exc = ValueError('not enough values to unpack (expected 2, got 1)')

    def handle_exception(self, exc):
        """
        Handle any exception that occurs, by returning an appropriate response,
        or re-raising the error.
        """
        if isinstance(exc, (exceptions.NotAuthenticated,
                            exceptions.AuthenticationFailed)):
            # WWW-Authenticate header for 401 responses, else coerce to 403
            auth_header = self.get_authenticate_header(self.request)
    
            if auth_header:
                exc.auth_header = auth_header
            else:
                exc.status_code = status.HTTP_403_FORBIDDEN
    
        exception_handler = self.get_exception_handler()
    
        context = self.get_exception_handler_context()
        response = exception_handler(exc, context)
    
        if response is None:
>           self.raise_uncaught_exception(exc)

.venv/lib/python3.12............/site-packages/rest_framework/views.py:469: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.events.api.events.EventViewSet object at 0x7f7f7289ecc0>
exc = ValueError('not enough values to unpack (expected 2, got 1)')

    def raise_uncaught_exception(self, exc):
        if settings.DEBUG:
            request = self.request
            renderer_format = getattr(request.accepted_renderer, 'format')
            use_plaintext_traceback = renderer_format not in ('html', 'api', 'admin')
            request.force_plaintext_errors(use_plaintext_traceback)
>       raise exc

.venv/lib/python3.12............/site-packages/rest_framework/views.py:480: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.events.api.events.EventViewSet object at 0x7f7f7289ecc0>
request = <rest_framework.request.Request: GET '.../v3/events/events/?context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'>
args = (), kwargs = {}
handler = <bound method ListModelMixin.list of <authentik.events.api.events.EventViewSet object at 0x7f7f7289ecc0>>

    def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?
    
        try:
            self.initial(request, *args, **kwargs)
    
            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
    
>           response = handler(request, *args, **kwargs)

.venv/lib/python3.12............/site-packages/rest_framework/views.py:506: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.events.api.events.EventViewSet object at 0x7f7f7289ecc0>
request = <rest_framework.request.Request: GET '.../v3/events/events/?context_model_pk=24&context_model_app=authentik_providers_oauth2&context_model_name=oauth2provider'>
args = (), kwargs = {}, queryset = <EventQuerySet []>
page = [<Event: Event action=model_created user={} context={'model': {'pk': 24, 'app': 'authentik_providers_oauth2', 'name': 'lnF44glGurecLWdku0MPw7rWVIhat5i9HyuhzECA', 'model_name': 'oauth2provider'}}>]
serializer = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] ListSerializer object at 0x7f7f72f410a0>

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
    
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
>           return self.get_paginated_response(serializer.data)

.venv/lib/python3.12.../site-packages/rest_framework/mixins.py:43: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] ListSerializer object at 0x7f7f72f410a0>

    @property
    def data(self):
>       ret = super().data

.venv/lib/python3.12...................../site-packages/rest_framework/serializers.py:768: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] ListSerializer object at 0x7f7f72f410a0>

    @property
    def data(self):
        if hasattr(self, 'initial_data') and not hasattr(self, '_validated_data'):
            msg = (
                'When a serializer is passed a `data` keyword argument you '
                'must call `.is_valid()` before attempting to access the '
                'serialized `.data` representation.\n'
                'You should either call `.is_valid()` first, '
                'or access `.initial_data` instead.'
            )
            raise AssertionError(msg)
    
        if not hasattr(self, '_data'):
            if self.instance is not None and not getattr(self, '_errors', None):
>               self._data = self.to_representation(self.instance)

.venv/lib/python3.12...................../site-packages/rest_framework/serializers.py:253: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] ListSerializer object at 0x7f7f72f410a0>
data = [<Event: Event action=model_created user={} context={'model': {'pk': 24, 'app': 'authentik_providers_oauth2', 'name': 'lnF44glGurecLWdku0MPw7rWVIhat5i9HyuhzECA', 'model_name': 'oauth2provider'}}>]

    def to_representation(self, data):
        """
        List of object instances -> List of dicts of primitive datatypes.
        """
        # Dealing with nested relationships, data can be a Manager,
        # so, first get a queryset from the Manager if needed
        iterable = data.all() if isinstance(data, models.Manager) else data
    
        return [
>           self.child.to_representation(item) for item in iterable
        ]

.venv/lib/python3.12...................../site-packages/rest_framework/serializers.py:687: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f7f72522840>
instance = <Event: Event action=model_created user={} context={'model': {'pk': 24, 'app': 'authentik_providers_oauth2', 'name': 'lnF44glGurecLWdku0MPw7rWVIhat5i9HyuhzECA', 'model_name': 'oauth2provider'}}>

    def to_representation(self, instance):
        """
        Object instance -> Dict of primitive datatypes.
        """
        ret = OrderedDict()
        fields = self._readable_fields
    
>       for field in fields:

.venv/lib/python3.12...................../site-packages/rest_framework/serializers.py:507: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f7f72522840>

    @property
    def _readable_fields(self):
>       for field in self.fields.values():

.venv/lib/python3.12...................../site-packages/rest_framework/serializers.py:368: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.utils.functional.cached_property object at 0x7f7f7d799a90>
instance = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f7f72522840>
cls = <class 'authentik.events.api.events.EventSerializer'>

    def __get__(self, instance, cls=None):
        """
        Call the function and put the return value in instance.__dict__ so that
        subsequent attribute access on the instance returns the cached value
        instead of calling cached_property.__get__().
        """
        if instance is None:
            return self
>       res = instance.__dict__[self.name] = self.func(instance)

.venv/lib/python3.12.../django/utils/functional.py:47: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f7f72522840>

    @cached_property
    def fields(self):
        """
        A dictionary of {field_name: field_instance}.
        """
        # `fields` is evaluated lazily. We do this to ensure that we don't
        # have issues importing modules that use ModelSerializers as fields,
        # even if Django's app-loading stage has not yet run.
        fields = BindingDict(self)
>       for key, value in self.get_fields().items():

.venv/lib/python3.12...................../site-packages/rest_framework/serializers.py:356: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f7f72522840>

    def get_fields(self):
        """
        Return the dict of field names -> field instances that should be
        used for `self.fields` when instantiating the serializer.
        """
        if self.url_field_name is None:
            self.url_field_name = api_settings.URL_FIELD_NAME
    
        assert hasattr(self, 'Meta'), (
            'Class {serializer_class} missing "Meta" attribute'.format(
                serializer_class=self.__class__.__name__
            )
        )
        assert hasattr(self.Meta, 'model'), (
            'Class {serializer_class} missing "Meta.model" attribute'.format(
                serializer_class=self.__class__.__name__
            )
        )
        if model_meta.is_abstract_model(self.Meta.model):
            raise ValueError(
                'Cannot use ModelSerializer with Abstract Models.'
            )
    
        declared_fields = copy.deepcopy(self._declared_fields)
        model = getattr(self.Meta, 'model')
        depth = getattr(self.Meta, 'depth', 0)
    
        if depth is not None:
            assert depth >= 0, "'depth' may not be negative."
            assert depth <= 10, "'depth' may not be greater than 10."
    
        # Retrieve metadata about fields & relationships on the model class.
        info = model_meta.get_field_info(model)
        field_names = self.get_field_names(declared_fields, info)
    
        # Determine any extra field arguments and hidden fields that
        # should be included
        extra_kwargs = self.get_extra_kwargs()
        extra_kwargs, hidden_fields = self.get_uniqueness_extra_kwargs(
            field_names, declared_fields, extra_kwargs
        )
    
        # Determine the fields that should be included on the serializer.
        fields = OrderedDict()
    
        for field_name in field_names:
            # If the field is explicitly declared on the class then use that.
            if field_name in declared_fields:
                fields[field_name] = declared_fields[field_name]
                continue
    
            extra_field_kwargs = extra_kwargs.get(field_name, {})
            source = extra_field_kwargs.get('source', '*')
            if source == '*':
                source = field_name
    
            # Determine the serializer field class and keyword arguments.
            field_class, field_kwargs = self.build_field(
                source, info, model, depth
            )
    
            # Include any kwargs defined in `Meta.extra_kwargs`
            field_kwargs = self.include_extra_kwargs(
                field_kwargs, extra_field_kwargs
            )
    
            # Create the serializer field.
>           fields[field_name] = field_class(**field_kwargs)

.venv/lib/python3.12...................../site-packages/rest_framework/serializers.py:1086: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = IPAddressField(allow_null=True, required=False), protocol = 'both'
kwargs = {'allow_null': True, 'required': False}

    def __init__(self, protocol='both', **kwargs):
        self.protocol = protocol.lower()
        self.unpack_ipv4 = (self.protocol == 'both')
        super().__init__(**kwargs)
>       validators, error_message = ip_address_validators(protocol, self.unpack_ipv4)
E       ValueError: not enough values to unpack (expected 2, got 1)

.venv/lib/python3.12.../site-packages/rest_framework/fields.py:862: ValueError
authentik.api.tests.test_schema.TestSchemaGeneration::test_schema
Stack Traces | 0.862s run time
self = <unittest.case._Outcome object at 0x7f1679ba2390>
test_case = <authentik.api.tests.test_schema.TestSchemaGeneration testMethod=test_schema>
subTest = False

    @contextlib.contextmanager
    def testPartExecutor(self, test_case, subTest=False):
        old_success = self.success
        self.success = True
        try:
>           yield

.../hostedtoolcache/Python/3.12.9........./x64/lib/python3.12/unittest/case.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.api.tests.test_schema.TestSchemaGeneration testMethod=test_schema>
result = <TestCaseFunction test_schema>

    def run(self, result=None):
        if result is None:
            result = self.defaultTestResult()
            startTestRun = getattr(result, 'startTestRun', None)
            stopTestRun = getattr(result, 'stopTestRun', None)
            if startTestRun is not None:
                startTestRun()
        else:
            stopTestRun = None
    
        result.startTest(self)
        try:
            testMethod = getattr(self, self._testMethodName)
            if (getattr(self.__class__, "__unittest_skip__", False) or
                getattr(testMethod, "__unittest_skip__", False)):
                # If the class or method was skipped.
                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
                            or getattr(testMethod, '__unittest_skip_why__', ''))
                _addSkip(result, self, skip_why)
                return result
    
            expecting_failure = (
                getattr(self, "__unittest_expecting_failure__", False) or
                getattr(testMethod, "__unittest_expecting_failure__", False)
            )
            outcome = _Outcome(result)
            start_time = time.perf_counter()
            try:
                self._outcome = outcome
    
                with outcome.testPartExecutor(self):
                    self._callSetUp()
                if outcome.success:
                    outcome.expecting_failure = expecting_failure
                    with outcome.testPartExecutor(self):
>                       self._callTestMethod(testMethod)

.../hostedtoolcache/Python/3.12.9........./x64/lib/python3.12/unittest/case.py:634: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.api.tests.test_schema.TestSchemaGeneration testMethod=test_schema>
method = <bound method TestSchemaGeneration.test_schema of <authentik.api.tests.test_schema.TestSchemaGeneration testMethod=test_schema>>

    def _callTestMethod(self, method):
>       if method() is not None:

.../hostedtoolcache/Python/3.12.9........./x64/lib/python3.12/unittest/case.py:589: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.api.tests.test_schema.TestSchemaGeneration testMethod=test_schema>

    def test_schema(self):
        """Test generation"""
>       response = self.client.get(
            reverse("authentik_api:schema"),
        )

.../api/tests/test_schema.py:13: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f1675051730>
path = '...................................................................../api/v3/schema/', data = None, follow = False, extra = {}

    def get(self, path, data=None, follow=False, **extra):
>       response = super().get(path, data=data, **extra)

.venv/lib/python3.12.............../site-packages/rest_framework/test.py:289: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f1675051730>
path = '...................................................................../api/v3/schema/', data = None, extra = {}, r = {'QUERY_STRING': ''}

    def get(self, path, data=None, **extra):
        r = {
            'QUERY_STRING': urlencode(data or {}, doseq=True),
        }
        if not data and '?' in path:
            # Fix to support old behavior where you have the arguments in the
            # url. See #1461.
            query_string = force_bytes(path.split('?')[1])
            query_string = query_string.decode('iso-8859-1')
            r['QUERY_STRING'] = query_string
        r.update(extra)
>       return self.generic('GET', path, **r)

.venv/lib/python3.12.............../site-packages/rest_framework/test.py:206: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f1675051730>, method = 'GET'
path = '...................................................................../api/v3/schema/', data = '', content_type = 'application/octet-stream'
secure = False
extra = {'CONTENT_TYPE': 'application/octet-stream', 'QUERY_STRING': ''}

    def generic(self, method, path, data='',
                content_type='application/octet-stream', secure=False, **extra):
        # Include the CONTENT_TYPE, regardless of whether or not data is empty.
        if content_type is not None:
            extra['CONTENT_TYPE'] = str(content_type)
    
>       return super().generic(
            method, path, data, content_type, secure, **extra)

.venv/lib/python3.12.............../site-packages/rest_framework/test.py:234: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f1675051730>, method = 'GET'
path = '...................................................................../api/v3/schema/', data = b'', content_type = 'application/octet-stream'
secure = False, headers = None, query_params = None
extra = {'CONTENT_TYPE': 'application/octet-stream', 'QUERY_STRING': ''}
parsed = ParseResult(scheme='', netloc='', path='...................................................................../api/v3/schema/', params='', query='', fragment='')
r = {'CONTENT_TYPE': 'application/octet-stream', 'PATH_INFO': '...................................................................../api/v3/schema/', 'QUERY_STRING': '', 'REQUEST_METHOD': 'GET', ...}
query_string = ''

    def generic(
        self,
        method,
        path,
        data="",
        content_type="application/octet-stream",
        secure=False,
        *,
        headers=None,
        query_params=None,
        **extra,
    ):
        """Construct an arbitrary HTTP request."""
        parsed = urlparse(str(path))  # path can be lazy
        data = force_bytes(data, settings.DEFAULT_CHARSET)
        r = {
            "PATH_INFO": self._get_path(parsed),
            "REQUEST_METHOD": method,
            "SERVER_PORT": "443" if secure else "80",
            "wsgi.url_scheme": "https" if secure else "http",
        }
        if data:
            r.update(
                {
                    "CONTENT_LENGTH": str(len(data)),
                    "CONTENT_TYPE": content_type,
                    "wsgi.input": FakePayload(data),
                }
            )
        if headers:
            extra.update(HttpHeaders.to_wsgi_names(headers))
        if query_params:
            extra["QUERY_STRING"] = urlencode(query_params, doseq=True)
        r.update(extra)
        # If QUERY_STRING is absent or empty, we want to extract it from the URL.
        if not r.get("QUERY_STRING"):
            # WSGI requires latin-1 encoded strings. See get_path_info().
            query_string = parsed[4].encode().decode("iso-8859-1")
            r["QUERY_STRING"] = query_string
>       return self.request(**r)

.venv/lib/python3.12.../django/test/client.py:676: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f1675051730>
kwargs = {'CONTENT_TYPE': 'application/octet-stream', 'PATH_INFO': '...................................................................../api/v3/schema/', 'QUERY_STRING': '', 'REQUEST_METHOD': 'GET', ...}

    def request(self, **kwargs):
        # Ensure that any credentials set get added to every request.
        kwargs.update(self._credentials)
>       return super().request(**kwargs)

.venv/lib/python3.12.............../site-packages/rest_framework/test.py:286: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f1675051730>
kwargs = {'CONTENT_TYPE': 'application/octet-stream', 'PATH_INFO': '...................................................................../api/v3/schema/', 'QUERY_STRING': '', 'REQUEST_METHOD': 'GET', ...}

    def request(self, **kwargs):
>       request = super().request(**kwargs)

.venv/lib/python3.12.............../site-packages/rest_framework/test.py:238: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f1675051730>
request = {'CONTENT_TYPE': 'application/octet-stream', 'PATH_INFO': '...................................................................../api/v3/schema/', 'QUERY_STRING': '', 'REQUEST_METHOD': 'GET', ...}
environ = {'CONTENT_TYPE': 'application/octet-stream', 'HTTP_COOKIE': '', 'PATH_INFO': '...................................................................../api/v3/schema/', 'QUERY_STRING': '', ...}
data = {'context': [[{'True': True, 'False': False, 'None': None}, {'csrf_token': <SimpleLazyObject: <function csrf.<locals>....se/ske...">, <Template template_string="{% load static %}{%...">, <Template template_string="{% load i18n %}{% g...">]}
on_template_render = functools.partial(<function store_rendered_templates at 0x7f1683f79120>, {'templates': [<Template template_string="{% ...<IncludeNode: template=<FilterExpression '"base/header_js.html"'>>, <TextNode: '\n'>]>}, {'LANGUAGE_CODE': 'en-us'}]]})
signal_uid = 'template-render-139734503414400'
exception_uid = 'request-exception-139734503414400'
response = <ServerErrorTemplateResponse status_code=500, "text/html; charset=utf-8">

    def request(self, **request):
        """
        Make a generic request. Compose the environment dictionary and pass
        to the handler, return the result of the handler. Assume defaults for
        the query environment, which can be overridden using the arguments to
        the request.
        """
        environ = self._base_environ(**request)
    
        # Curry a data dictionary into an instance of the template renderer
        # callback function.
        data = {}
        on_template_render = partial(store_rendered_templates, data)
        signal_uid = "template-render-%s" % id(request)
        signals.template_rendered.connect(on_template_render, dispatch_uid=signal_uid)
        # Capture exceptions created by the handler.
        exception_uid = "request-exception-%s" % id(request)
        got_request_exception.connect(self.store_exc_info, dispatch_uid=exception_uid)
        try:
            response = self.handler(environ)
        finally:
            signals.template_rendered.disconnect(dispatch_uid=signal_uid)
            got_request_exception.disconnect(dispatch_uid=exception_uid)
        # Check for signaled exceptions.
>       self.check_exception(response)

.venv/lib/python3.12.../django/test/client.py:1092: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.APIClient object at 0x7f1675051730>
response = <ServerErrorTemplateResponse status_code=500, "text/html; charset=utf-8">

    def check_exception(self, response):
        """
        Look for a signaled exception, clear the current context exception
        data, re-raise the signaled exception, and clear the signaled exception
        from the local cache.
        """
        response.exc_info = self.exc_info
        if self.exc_info:
            _, exc_value, _ = self.exc_info
            self.exc_info = None
            if self.raise_request_exception:
>               raise exc_value

.venv/lib/python3.12.../django/test/client.py:805: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

request = <WSGIRequest: GET '...................................................................../api/v3/schema/'>

    @wraps(get_response)
    def inner(request):
        try:
>           response = get_response(request)

.venv/lib/python3.12.../core/handlers/exception.py:55: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <rest_framework.test.ForceAuthClientHandler object at 0x7f1679d05b80>
request = <WSGIRequest: GET '...................................................................../api/v3/schema/'>

    def _get_response(self, request):
        """
        Resolve and call the view, then apply view, exception, and
        template_response middleware. This method is everything that happens
        inside the request/response middleware.
        """
        response = None
        callback, callback_args, callback_kwargs = self.resolve_request(request)
    
        # Apply view middleware
        for middleware_method in self._view_middleware:
            response = middleware_method(
                request, callback, callback_args, callback_kwargs
            )
            if response:
                break
    
        if response is None:
            wrapped_callback = self.make_view_atomic(callback)
            # If it is an asynchronous view, run it in a subthread.
            if iscoroutinefunction(wrapped_callback):
                wrapped_callback = async_to_sync(wrapped_callback)
            try:
>               response = wrapped_callback(request, *callback_args, **callback_kwargs)

.venv/lib/python3.12.../core/handlers/base.py:197: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

request = <WSGIRequest: GET '...................................................................../api/v3/schema/'>, args = (), kwargs = {}
current_scope = <Scope id=0x7f1686815fc0 name=None type=ScopeType.CURRENT>
sentry_scope = <Scope id=0x7f16872efa00 name=None type=ScopeType.ISOLATION>

    @functools.wraps(callback)
    def sentry_wrapped_callback(request, *args, **kwargs):
        # type: (Any, *Any, **Any) -> Any
        current_scope = sentry_sdk.get_current_scope()
        if current_scope.transaction is not None:
            current_scope.transaction.update_active_thread()
    
        sentry_scope = sentry_sdk.get_isolation_scope()
        # set the active thread id to the handler thread for sync views
        # this isn't necessary for async views since that runs on main
        if sentry_scope.profile is not None:
            sentry_scope.profile.update_active_thread_id()
    
        with sentry_sdk.start_span(
            op=OP.VIEW_RENDER,
            name=request.resolver_match.view_name,
            origin=DjangoIntegration.origin,
        ):
>           return callback(request, *args, **kwargs)

.venv/lib/python3.12.../integrations/django/views.py:94: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

request = <WSGIRequest: GET '...................................................................../api/v3/schema/'>, args = (), kwargs = {}
result = None

    def _view_wrapper(request, *args, **kwargs):
        result = _pre_process_request(request, *args, **kwargs)
        if result is not None:
            return result
    
        try:
            response = view_func(request, *args, **kwargs)
        except Exception as e:
>           result = _process_exception(request, e)

.venv/lib/python3.12.../django/utils/decorators.py:188: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

request = <WSGIRequest: GET '...................................................................../api/v3/schema/'>, args = (), kwargs = {}
result = None

    def _view_wrapper(request, *args, **kwargs):
        result = _pre_process_request(request, *args, **kwargs)
        if result is not None:
            return result
    
        try:
>           response = view_func(request, *args, **kwargs)

.venv/lib/python3.12.../django/utils/decorators.py:186: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

request = <WSGIRequest: GET '...................................................................../api/v3/schema/'>, args = (), kwargs = {}

    def _view_wrapper(request, *args, **kwargs):
>       return view_func(request, *args, **kwargs)

.venv/lib/python3.12.../views/decorators/csrf.py:65: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

request = <WSGIRequest: GET '...................................................................../api/v3/schema/'>, args = (), kwargs = {}
self = <drf_spectacular.views.SpectacularAPIView object at 0x7f1679815ca0>

    def view(request, *args, **kwargs):
        self = cls(**initkwargs)
        self.setup(request, *args, **kwargs)
        if not hasattr(self, "request"):
            raise AttributeError(
                "%s instance has no 'request' attribute. Did you override "
                "setup() and forget to call super()?" % cls.__name__
            )
>       return self.dispatch(request, *args, **kwargs)

.venv/lib/python3.12.../views/generic/base.py:104: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.views.SpectacularAPIView object at 0x7f1679815ca0>
request = <rest_framework.request.Request: GET '...................................................................../api/v3/schema/'>, args = ()
kwargs = {}
handler = <bound method SpectacularAPIView.get of <drf_spectacular.views.SpectacularAPIView object at 0x7f1679815ca0>>

    def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?
    
        try:
            self.initial(request, *args, **kwargs)
    
            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
    
            response = handler(request, *args, **kwargs)
    
        except Exception as exc:
>           response = self.handle_exception(exc)

.venv/lib/python3.12............/site-packages/rest_framework/views.py:509: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.views.SpectacularAPIView object at 0x7f1679815ca0>
exc = ValueError('not enough values to unpack (expected 2, got 1)')

    def handle_exception(self, exc):
        """
        Handle any exception that occurs, by returning an appropriate response,
        or re-raising the error.
        """
        if isinstance(exc, (exceptions.NotAuthenticated,
                            exceptions.AuthenticationFailed)):
            # WWW-Authenticate header for 401 responses, else coerce to 403
            auth_header = self.get_authenticate_header(self.request)
    
            if auth_header:
                exc.auth_header = auth_header
            else:
                exc.status_code = status.HTTP_403_FORBIDDEN
    
        exception_handler = self.get_exception_handler()
    
        context = self.get_exception_handler_context()
        response = exception_handler(exc, context)
    
        if response is None:
>           self.raise_uncaught_exception(exc)

.venv/lib/python3.12............/site-packages/rest_framework/views.py:469: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.views.SpectacularAPIView object at 0x7f1679815ca0>
exc = ValueError('not enough values to unpack (expected 2, got 1)')

    def raise_uncaught_exception(self, exc):
        if settings.DEBUG:
            request = self.request
            renderer_format = getattr(request.accepted_renderer, 'format')
            use_plaintext_traceback = renderer_format not in ('html', 'api', 'admin')
            request.force_plaintext_errors(use_plaintext_traceback)
>       raise exc

.venv/lib/python3.12............/site-packages/rest_framework/views.py:480: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.views.SpectacularAPIView object at 0x7f1679815ca0>
request = <rest_framework.request.Request: GET '...................................................................../api/v3/schema/'>, args = ()
kwargs = {}
handler = <bound method SpectacularAPIView.get of <drf_spectacular.views.SpectacularAPIView object at 0x7f1679815ca0>>

    def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?
    
        try:
            self.initial(request, *args, **kwargs)
    
            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
    
>           response = handler(request, *args, **kwargs)

.venv/lib/python3.12............/site-packages/rest_framework/views.py:506: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.views.SpectacularAPIView object at 0x7f1679815ca0>
request = <rest_framework.request.Request: GET '...................................................................../api/v3/schema/'>, args = ()
kwargs = {}

    @extend_schema(**SCHEMA_KWARGS)
    def get(self, request, *args, **kwargs):
        # special handling of custom urlconf parameter
        if isinstance(self.urlconf, list) or isinstance(self.urlconf, tuple):
            ModuleWrapper = namedtuple('ModuleWrapper', ['urlpatterns'])
            if all(isinstance(i, str) for i in self.urlconf):
                # list of import string for urlconf
                patterns = []
                for item in self.urlconf:
                    url = import_module(item)
                    patterns += url.urlpatterns
                self.urlconf = ModuleWrapper(tuple(patterns))
            else:
                # explicitly resolved urlconf
                self.urlconf = ModuleWrapper(tuple(self.urlconf))
    
        with patched_settings(self.custom_settings):
            if settings.USE_I18N and request.GET.get('lang'):
                with translation.override(request.GET.get('lang')):
                    return self._get_schema_response(request)
            else:
>               return self._get_schema_response(request)

.venv/lib/python3.12....../site-packages/drf_spectacular/views.py:84: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.views.SpectacularAPIView object at 0x7f1679815ca0>
request = <rest_framework.request.Request: GET '...................................................................../api/v3/schema/'>

    def _get_schema_response(self, request):
        # version specified as parameter to the view always takes precedence. after
        # that we try to source version through the schema view's own versioning_class.
        version = self.api_version or request.version or self._get_version_parameter(request)
        generator = self.generator_class(urlconf=self.urlconf, api_version=version, patterns=self.patterns)
        return Response(
>           data=generator.get_schema(request=request, public=self.serve_public),
            headers={"Content-Disposition": f'inline; filename="{self._get_filename(request, version)}"'}
        )

.venv/lib/python3.12....../site-packages/drf_spectacular/views.py:92: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.generators.SchemaGenerator object at 0x7f1679815310>
request = <rest_framework.request.Request: GET '...................................................................../api/v3/schema/'>, public = True

    def get_schema(self, request=None, public=False):
        """ Generate a OpenAPI schema. """
        reset_generator_stats()
        result = build_root_object(
>           paths=self.parse(request, public),
            components=self.registry.build(spectacular_settings.APPEND_COMPONENTS),
            webhooks=process_webhooks(spectacular_settings.WEBHOOKS, self.registry),
            version=self.api_version or getattr(request, 'version', None),
        )

.venv/lib/python3.12....../site-packages/drf_spectacular/generators.py:285: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.generators.SchemaGenerator object at 0x7f1679815310>
input_request = <rest_framework.request.Request: GET '...................................................................../api/v3/schema/'>
public = True

    def parse(self, input_request, public):
        """ Iterate endpoints generating per method path operations. """
        result = {}
        self._initialise_endpoints()
        endpoints = self._get_paths_and_endpoints()
    
        if spectacular_settings.SCHEMA_PATH_PREFIX is None:
            # estimate common path prefix if none was given. only use it if we encountered more
            # than one view to prevent emission of erroneous and unnecessary fallback names.
            non_trivial_prefix = len(set([view.__class__ for _, _, _, view in endpoints])) > 1
            if non_trivial_prefix:
                path_prefix = os.path.commonpath([path for path, _, _, _ in endpoints])
                path_prefix = re.escape(path_prefix)  # guard for RE special chars in path
            else:
                path_prefix = '/'
        else:
            path_prefix = spectacular_settings.SCHEMA_PATH_PREFIX
        if not path_prefix.startswith('^'):
            path_prefix = '^' + path_prefix  # make sure regex only matches from the start
    
        for path, path_regex, method, view in endpoints:
            # emit queued up warnings/error that happened prior to generation (decoration)
            for w in get_override(view, 'warnings', []):
                warn(w)
            for e in get_override(view, 'errors', []):
                error(e)
    
            view.request = spectacular_settings.GET_MOCK_REQUEST(method, path, view, input_request)
    
            if not (public or self.has_view_permissions(path, method, view)):
                continue
    
            if view.versioning_class and not is_versioning_supported(view.versioning_class):
                warn(
                    f'using unsupported versioning class "{view.versioning_class}". view will be '
                    f'processed as unversioned view.'
                )
            elif view.versioning_class:
                version = (
                    self.api_version  # explicit version from CLI, SpecView or SpecView request
                    or view.versioning_class.default_version  # fallback
                )
                if not version:
                    continue
                path = modify_for_versioning(self.inspector.patterns, method, path, view, version)
                if not operation_matches_version(view, version):
                    continue
    
            assert isinstance(view.schema, AutoSchema), (
                f'Incompatible AutoSchema used on View {view.__class__}. Is DRF\'s '
                f'DEFAULT_SCHEMA_CLASS pointing to "drf_spectacular.openapi.AutoSchema" '
                f'or any other drf-spectacular compatible AutoSchema?'
            )
            with add_trace_message(getattr(view, '__class__', view)):
>               operation = view.schema.get_operation(
                    path, path_regex, path_prefix, method, self.registry
                )

.venv/lib/python3.12....../site-packages/drf_spectacular/generators.py:256: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.openapi.AutoSchema object at 0x7f1676de20c0>
path = '.../v3/events/events/', path_regex = 'api/v3/^events/events/$'
path_prefix = '^/api/v([0-9]+(beta)?)', method = 'GET'
registry = <drf_spectacular.plumbing.ComponentRegistry object at 0x7f1679817e60>

    def get_operation(
            self,
            path: str,
            path_regex: str,
            path_prefix: str,
            method: str,
            registry: ComponentRegistry
    ) -> Optional[_SchemaType]:
        self.registry = registry
        self.path = path
        self.path_regex = path_regex
        self.path_prefix = path_prefix
        self.method = method.upper()
    
        if self.is_excluded():
            return None
    
        operation: _SchemaType = {'operationId': self.get_operation_id()}
    
        description = self.get_description()
        if description:
            operation['description'] = description
    
        summary = self.get_summary()
        if summary:
            operation['summary'] = summary
    
        external_docs = self._get_external_docs()
        if external_docs:
            operation['externalDocs'] = external_docs
    
        parameters = self._get_parameters()
        if parameters:
            operation['parameters'] = parameters
    
        tags = self.get_tags()
        if tags:
            operation['tags'] = tags
    
        request_body = self._get_request_body()
        if request_body:
            operation['requestBody'] = request_body
    
        auth = self.get_auth()
        if auth:
            operation['security'] = auth
    
        deprecated = self.is_deprecated()
        if deprecated:
            operation['deprecated'] = deprecated
    
>       operation['responses'] = self._get_response_bodies()

.venv/lib/python3.12................../site-packages/drf_spectacular/openapi.py:112: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.openapi.AutoSchema object at 0x7f1676de20c0>
direction = 'response'

    def _get_response_bodies(self, direction: Direction = 'response') -> _SchemaType:
        response_serializers = self.get_response_serializers()
    
        if (
            is_serializer(response_serializers)
            or is_basic_type(response_serializers)
            or is_higher_order_type_hint(response_serializers)
            or isinstance(response_serializers, OpenApiResponse)
        ):
            if self.method == 'DELETE':
                return {'204': {'description': _('No response body')}}
            if self._is_create_operation():
                return {'201': self._get_response_for_code(response_serializers, '201', direction=direction)}
>           return {'200': self._get_response_for_code(response_serializers, '200', direction=direction)}

.venv/lib/python3.12................../site-packages/drf_spectacular/openapi.py:1397: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.openapi.AutoSchema object at 0x7f1676de20c0>
serializer = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f1676de1880>
status_code = '200', media_types = None, direction = 'response'

    def _get_response_for_code(self, serializer, status_code, media_types=None, direction='response'):
        if isinstance(serializer, OpenApiResponse):
            serializer, description, examples = (
                serializer.response, serializer.description, serializer.examples
            )
        else:
            description, examples = '', []
    
        serializer = force_instance(serializer)
        headers = self._get_response_headers_for_code(status_code, direction)
        headers = {'headers': headers} if headers else {}
    
        if not serializer:
            return {**headers, 'description': description or _('No response body')}
        elif is_list_serializer(serializer):
            schema = self._unwrap_list_serializer(serializer.child, direction)
            if not schema:
                return {**headers, 'description': description or _('No response body')}
        elif is_serializer(serializer):
>           component = self.resolve_serializer(serializer, direction)

.venv/lib/python3.12................../site-packages/drf_spectacular/openapi.py:1453: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.openapi.AutoSchema object at 0x7f1676de20c0>
serializer = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f1676de1880>
direction = 'response', bypass_extensions = False

    def resolve_serializer(
            self, serializer: _SerializerType, direction: Direction, bypass_extensions=False
    ) -> ResolvedComponent:
        assert_basic_serializer(serializer)
        serializer = force_instance(serializer)
    
        with add_trace_message(serializer.__class__):
            component = ResolvedComponent(
                name=self._get_serializer_name(serializer, direction, bypass_extensions),
                type=ResolvedComponent.SCHEMA,
                object=self.get_serializer_identity(serializer, direction),
            )
            if component in self.registry:
                return self.registry[component]  # return component with schema
    
            self.registry.register(component)
>           component.schema = self._map_serializer(serializer, direction, bypass_extensions)

.venv/lib/python3.12................../site-packages/drf_spectacular/openapi.py:1648: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.openapi.AutoSchema object at 0x7f1676de20c0>
serializer = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f1676de1880>
direction = 'response', bypass_extensions = False

    def _map_serializer(self, serializer, direction, bypass_extensions=False):
        serializer = force_instance(serializer)
        serializer_extension = OpenApiSerializerExtension.get_match(serializer)
    
        if serializer_extension and not bypass_extensions:
            schema = serializer_extension.map_serializer(self, direction)
        else:
>           schema = self._map_basic_serializer(serializer, direction)

.venv/lib/python3.12................../site-packages/drf_spectacular/openapi.py:949: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <drf_spectacular.openapi.AutoSchema object at 0x7f1676de20c0>
serializer = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f1676de1880>
direction = 'response'

    def _map_basic_serializer(self, serializer, direction):
        assert_basic_serializer(serializer)
        serializer = force_instance(serializer)
        # serializers provided through @extend_schema will not receive the mock context
        # via _get_serializer(). Establish behavioral symmetry for those use-cases.
        if not serializer.context:
            serializer.context.update(build_serializer_context(self.view))
        required = set()
        properties = {}
    
>       for field in serializer.fields.values():

.venv/lib/python3.12................../site-packages/drf_spectacular/openapi.py:1042: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <django.utils.functional.cached_property object at 0x7f1684191c70>
instance = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f1676de1880>
cls = <class 'authentik.events.api.events.EventSerializer'>

    def __get__(self, instance, cls=None):
        """
        Call the function and put the return value in instance.__dict__ so that
        subsequent attribute access on the instance returns the cached value
        instead of calling cached_property.__get__().
        """
        if instance is None:
            return self
>       res = instance.__dict__[self.name] = self.func(instance)

.venv/lib/python3.12.../django/utils/functional.py:47: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f1676de1880>

    @cached_property
    def fields(self):
        """
        A dictionary of {field_name: field_instance}.
        """
        # `fields` is evaluated lazily. We do this to ensure that we don't
        # have issues importing modules that use ModelSerializers as fields,
        # even if Django's app-loading stage has not yet run.
        fields = BindingDict(self)
>       for key, value in self.get_fields().items():

.venv/lib/python3.12....../site-packages/rest_framework/serializers.py:356: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[ValueError('not enough values to unpack (expected 2, got 1)') raised in repr()] EventSerializer object at 0x7f1676de1880>

    def get_fields(self):
        """
        Return the dict of field names -> field instances that should be
        used for `self.fields` when instantiating the serializer.
        """
        if self.url_field_name is None:
            self.url_field_name = api_settings.URL_FIELD_NAME
    
        assert hasattr(self, 'Meta'), (
            'Class {serializer_class} missing "Meta" attribute'.format(
                serializer_class=self.__class__.__name__
            )
        )
        assert hasattr(self.Meta, 'model'), (
            'Class {serializer_class} missing "Meta.model" attribute'.format(
                serializer_class=self.__class__.__name__
            )
        )
        if model_meta.is_abstract_model(self.Meta.model):
            raise ValueError(
                'Cannot use ModelSerializer with Abstract Models.'
            )
    
        declared_fields = copy.deepcopy(self._declared_fields)
        model = getattr(self.Meta, 'model')
        depth = getattr(self.Meta, 'depth', 0)
    
        if depth is not None:
            assert depth >= 0, "'depth' may not be negative."
            assert depth <= 10, "'depth' may not be greater than 10."
    
        # Retrieve metadata about fields & relationships on the model class.
        info = model_meta.get_field_info(model)
        field_names = self.get_field_names(declared_fields, info)
    
        # Determine any extra field arguments and hidden fields that
        # should be included
        extra_kwargs = self.get_extra_kwargs()
        extra_kwargs, hidden_fields = self.get_uniqueness_extra_kwargs(
            field_names, declared_fields, extra_kwargs
        )
    
        # Determine the fields that should be included on the serializer.
        fields = OrderedDict()
    
        for field_name in field_names:
            # If the field is explicitly declared on the class then use that.
            if field_name in declared_fields:
                fields[field_name] = declared_fields[field_name]
                continue
    
            extra_field_kwargs = extra_kwargs.get(field_name, {})
            source = extra_field_kwargs.get('source', '*')
            if source == '*':
                source = field_name
    
            # Determine the serializer field class and keyword arguments.
            field_class, field_kwargs = self.build_field(
                source, info, model, depth
            )
    
            # Include any kwargs defined in `Meta.extra_kwargs`
            field_kwargs = self.include_extra_kwargs(
                field_kwargs, extra_field_kwargs
            )
    
            # Create the serializer field.
>           fields[field_name] = field_class(**field_kwargs)

.venv/lib/python3.12....../site-packages/rest_framework/serializers.py:1086: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = IPAddressField(allow_null=True, required=False), protocol = 'both'
kwargs = {'allow_null': True, 'required': False}

    def __init__(self, protocol='both', **kwargs):
        self.protocol = protocol.lower()
        self.unpack_ipv4 = (self.protocol == 'both')
        super().__init__(**kwargs)
>       validators, error_message = ip_address_validators(protocol, self.unpack_ipv4)
E       ValueError: not enough values to unpack (expected 2, got 1)

.venv/lib/python3.12.../site-packages/rest_framework/fields.py:862: ValueError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@rissson
Copy link
Member

rissson commented Mar 24, 2025

Ah, seems like #13655 has a fix for this as well

@melizeche
Copy link
Member Author

@rissson gotcha! Thanks!

@melizeche melizeche closed this Mar 24, 2025
@melizeche melizeche deleted the fix/ci_uv_poetry branch June 18, 2025 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants