Skip to content

Search: Add breadcrumbs to search results in order to provide more context#2282

Open
Tschuppi81 wants to merge 44 commits intomasterfrom
feature/ogc-2880-search-results-with-path
Open

Search: Add breadcrumbs to search results in order to provide more context#2282
Tschuppi81 wants to merge 44 commits intomasterfrom
feature/ogc-2880-search-results-with-path

Conversation

@Tschuppi81
Copy link
Contributor

@Tschuppi81 Tschuppi81 commented Jan 6, 2026

Search: Add breadcrumbs to search results in order to provide more context

TYPE: Feature
LINK: ogc-2880

@linear
Copy link

linear bot commented Jan 6, 2026

@codecov
Copy link

codecov bot commented Jan 6, 2026

❌ 32 Tests Failed:

Tests completed Failed Passed Skipped
70 32 38 2
View the top 3 failed test(s) by shortest run time
tests/onegov/fsi/test_views_templates.py::test_send_template
Stack Traces | 0.147s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_send_template>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f4b061ae020>
dispatch = <function Framework.get_layout at 0x7f4b1ab94c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f4b061ae020>) not that of dispatch (<function Framework.get_layout at 0x7f4b1ab94c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_subscription.py::test_create_delete_reservation
Stack Traces | 0.15s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_create_delete_reservation>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f3a7da86340>
dispatch = <function Framework.get_layout at 0x7f3a903b4c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f3a7da86340>) not that of dispatch (<function Framework.get_layout at 0x7f3a903b4c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/landsgemeinde/test_views.py::test_view_suggestions
Stack Traces | 0.152s run time
fixturedef = <FixtureDef argname='landsgemeinde_app' scope='function' baseid='tests/onegov/landsgemeinde'>
request = <SubRequest 'landsgemeinde_app' for <Function test_view_suggestions>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/landsgemeinde/conftest.py:120: in landsgemeinde_app
    yield create_landsgemeinde_app(request, False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/landsgemeinde/conftest.py:79: in create_landsgemeinde_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7fd14f6b5b20>
dispatch = <function Framework.get_layout at 0x7fd167cd0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7fd14f6b5b20>) not that of dispatch (<function Framework.get_layout at 0x7fd167cd0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_templates.py::test_embed_template
Stack Traces | 0.154s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_embed_template>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f3a7ba4d580>
dispatch = <function Framework.get_layout at 0x7f3a903b4c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f3a7ba4d580>) not that of dispatch (<function Framework.get_layout at 0x7f3a903b4c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_subscription.py::test_reservation_details
Stack Traces | 0.156s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_reservation_details>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f3a7d67f100>
dispatch = <function Framework.get_layout at 0x7f3a903b4c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f3a7d67f100>) not that of dispatch (<function Framework.get_layout at 0x7f3a903b4c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/landsgemeinde/test_views.py::test_view_pages_cache
Stack Traces | 0.159s run time
fixturedef = <FixtureDef argname='landsgemeinde_app' scope='function' baseid='tests/onegov/landsgemeinde'>
request = <SubRequest 'landsgemeinde_app' for <Function test_view_pages_cache>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/landsgemeinde/conftest.py:120: in landsgemeinde_app
    yield create_landsgemeinde_app(request, False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/landsgemeinde/conftest.py:79: in create_landsgemeinde_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7fd14f66dee0>
dispatch = <function Framework.get_layout at 0x7fd167cd0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7fd14f66dee0>) not that of dispatch (<function Framework.get_layout at 0x7fd167cd0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_subscription.py::test_reservation_collection_view
Stack Traces | 0.182s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_reservation_collection_view>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f4b0577ede0>
dispatch = <function Framework.get_layout at 0x7f4b1ab94c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f4b0577ede0>) not that of dispatch (<function Framework.get_layout at 0x7f4b1ab94c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_subscription.py::test_own_reservations
Stack Traces | 0.209s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_own_reservations>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f3a7da6a840>
dispatch = <function Framework.get_layout at 0x7f3a903b4c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f3a7da6a840>) not that of dispatch (<function Framework.get_layout at 0x7f3a903b4c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_subscription.py::test_edit_reservation
Stack Traces | 0.213s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_edit_reservation>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f4b060d6520>
dispatch = <function Framework.get_layout at 0x7f4b1ab94c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f4b060d6520>) not that of dispatch (<function Framework.get_layout at 0x7f4b1ab94c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/landsgemeinde/test_views.py::test_views
Stack Traces | 0.324s run time
fixturedef = <FixtureDef argname='fts_landsgemeinde_app' scope='function' baseid='tests/onegov/landsgemeinde'>
request = <SubRequest 'fts_landsgemeinde_app' for <Function test_views>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/landsgemeinde/conftest.py:125: in fts_landsgemeinde_app
    yield create_landsgemeinde_app(request, True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/landsgemeinde/conftest.py:79: in create_landsgemeinde_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f4b02287c40>
dispatch = <function Framework.get_layout at 0x7f4b1ab94c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f4b02287c40>) not that of dispatch (<function Framework.get_layout at 0x7f4b1ab94c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_app.py::test_cache_control_when_logged_in
Stack Traces | 0.342s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_cache_control_when_logged_in>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5e70cc0>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5e70cc0>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/landsgemeinde/test_utils.py::test_update_ticker
Stack Traces | 0.359s run time
fixturedef = <FixtureDef argname='landsgemeinde_app' scope='function' baseid='tests/onegov/landsgemeinde'>
request = <SubRequest 'landsgemeinde_app' for <Function test_update_ticker>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/landsgemeinde/conftest.py:120: in landsgemeinde_app
    yield create_landsgemeinde_app(request, False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/landsgemeinde/conftest.py:79: in create_landsgemeinde_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7fd14f7ca2a0>
dispatch = <function Framework.get_layout at 0x7fd167cd0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7fd14f7ca2a0>) not that of dispatch (<function Framework.get_layout at 0x7fd167cd0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_browser.py::test_signature_workflow@browser
Stack Traces | 0.412s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_signature_workflow>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb66e6660>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb66e6660>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_browser.py::test_external_map_link@browser
Stack Traces | 0.447s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_external_map_link>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5b5f880>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5b5f880>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_browser.py::test_publication_workflow@browser
Stack Traces | 0.451s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_publication_workflow>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb6778400>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb6778400>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_browser.py::test_browse_directory_coordinates@browser
Stack Traces | 0.457s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_browse_directory_coordinates>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb67b5080>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb67b5080>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_app.py::test_allowed_application_id
Stack Traces | 0.465s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_allowed_application_id>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7fd14ee6f2e0>
dispatch = <function Framework.get_layout at 0x7fd167cd0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7fd14ee6f2e0>) not that of dispatch (<function Framework.get_layout at 0x7fd167cd0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_browser.py::test_browse_directory_uploads[Photo *= *.png|*.jpg]@browser
Stack Traces | 0.482s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_browse_directory_uploads[Photo *= *.png|*.jpg]>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5e9d4e0>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5e9d4e0>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_browser.py::test_upload_image_with_error@browser
Stack Traces | 0.518s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_upload_image_with_error>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5e73ce0>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5e73ce0>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_browser.py::test_browse_directory_uploads[Photo = *.png|*.jpg]@browser
Stack Traces | 0.532s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_browse_directory_uploads[Photo = *.png|*.jpg]>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5b13b00>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5b13b00>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_subscription.py::test_locked_course_event_reservations
Stack Traces | 0.542s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_locked_course_event_reservations>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f3a7d5f0220>
dispatch = <function Framework.get_layout at 0x7f3a903b4c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f3a7d5f0220>) not that of dispatch (<function Framework.get_layout at 0x7f3a903b4c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_search.py::test_basic_search
Stack Traces | 0.557s run time
fixturedef = <FixtureDef argname='fts_fsi_app' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fts_fsi_app' for <Function test_basic_search>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:105: in fts_fsi_app
    yield create_fsi_app(request, True, hashed_password)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f4b0571bec0>
dispatch = <function Framework.get_layout at 0x7f4b1ab94c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f4b0571bec0>) not that of dispatch (<function Framework.get_layout at 0x7f4b1ab94c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_subscription.py::test_subscription_to_a_course_event
Stack Traces | 0.588s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_subscription_to_a_course_event>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7fd152618180>
dispatch = <function Framework.get_layout at 0x7fd167cd0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7fd152618180>) not that of dispatch (<function Framework.get_layout at 0x7fd167cd0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/landsgemeinde/test_browser.py::test_ticker
Stack Traces | 0.807s run time
fixturedef = <FixtureDef argname='wsgi_server' scope='function' baseid='tests/onegov/landsgemeinde'>
request = <SubRequest 'wsgi_server' for <Function test_ticker>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/landsgemeinde/conftest.py:143: in wsgi_server
    app = create_landsgemeinde_app(request, False, websocket_config)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/landsgemeinde/conftest.py:79: in create_landsgemeinde_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f3a7bf3f380>
dispatch = <function Framework.get_layout at 0x7f3a903b4c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f3a7bf3f380>) not that of dispatch (<function Framework.get_layout at 0x7f3a903b4c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_browser.py::test_browse_activities@browser
Stack Traces | 1.61s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_browse_activities>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5b756c0>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5b756c0>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_browser.py::test_rejected_reservation_sends_email_to_configured_recipients@browser
Stack Traces | 1.77s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_rejected_reservation_sends_email_to_configured_recipients>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5b48d60>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5b48d60>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/org/test_browser.py::test_context_specific_function_are_displayed_in_person_directory@browser
Stack Traces | 1.88s run time
fixturedef = <FixtureDef argname='org_app' scope='function' baseid='tests/onegov/org'>
request = <SubRequest 'org_app' for <Function test_context_specific_function_are_displayed_in_person_directory>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/org/conftest.py:202: in org_app
    yield create_org_app(request, enable_search=False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/org/conftest.py:253: in create_org_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5e06340>
dispatch = <function Framework.get_layout at 0x7f2bcb5b0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f2bb5e06340>) not that of dispatch (<function Framework.get_layout at 0x7f2bcb5b0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_course_event.py::test_add_subscription_for_other_attendee
Stack Traces | 2.27s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_add_subscription_for_other_attendee>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f4b08fc6ca0>
dispatch = <function Framework.get_layout at 0x7f4b1ab94c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f4b08fc6ca0>) not that of dispatch (<function Framework.get_layout at 0x7f4b1ab94c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_course_event.py::test_edit_subscription_for_other_attendee
Stack Traces | 2.31s run time
fixturedef = <FixtureDef argname='fsi_app_mocked' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app_mocked' for <Function test_edit_subscription_for_other_attendee>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:97: in fsi_app_mocked
    yield create_fsi_app(request, False, hashed_password, mock_db=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f3a7ae92fc0>
dispatch = <function Framework.get_layout at 0x7f3a903b4c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f3a7ae92fc0>) not that of dispatch (<function Framework.get_layout at 0x7f3a903b4c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/intranet/test_views.py::test_view_permissions
Stack Traces | 2.96s run time
def test_view_permissions() -> None:
>       utils.assert_explicit_permissions(onegov.org, IntranetApp)

.../onegov/intranet/test_views.py:10: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/shared/utils.py:164: in assert_explicit_permissions
    app_class.commit()
...................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
...................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
...................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
...................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
...................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f3a7bf3f1a0>
dispatch = <function Framework.get_layout at 0x7f3a903b4c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f3a7bf3f1a0>) not that of dispatch (<function Framework.get_layout at 0x7f3a903b4c20>)

...................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/fsi/test_views_course_event.py::test_delete_subscriptions_past_present
Stack Traces | 4.22s run time
fixturedef = <FixtureDef argname='fsi_app' scope='function' baseid='tests/onegov/fsi'>
request = <SubRequest 'fsi_app' for <Function test_delete_subscriptions_past_present>>

    @pytest.hookimpl(wrapper=True)
    def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
        asyncio_mode = _get_asyncio_mode(request.config)
        if not _is_asyncio_fixture_function(fixturedef.func):
            if asyncio_mode == Mode.STRICT:
                # Ignore async fixtures without explicit asyncio mark in strict mode
                # This applies to pytest_trio fixtures, for example
>               return (yield)
                        ^^^^^

......................../app/lib/python3.11.../site-packages/pytest_asyncio/plugin.py:728: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../onegov/fsi/conftest.py:89: in fsi_app
    yield create_fsi_app(request, False, hashed_password)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../onegov/fsi/conftest.py:241: in create_fsi_app
    app = create_app(
tests/shared/utils.py:199: in create_app
    app_class.commit()
......................../app/lib/python3.11....../site-packages/morepath/app.py:273: in commit
    return cls.mounted_app_classes(dectate.commit)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......................../app/lib/python3.11....../site-packages/morepath/app.py:259: in mounted_app_classes
    callback(*found)
......................../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
......................../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
......................../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
......................../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7fd1532c2fc0>
dispatch = <function Framework.get_layout at 0x7fd167cd0c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7fd1532c2fc0>) not that of dispatch (<function Framework.get_layout at 0x7fd167cd0c20>)

......................../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError
tests/onegov/onboarding/test_views.py::test_town_create
Stack Traces | 5.9s run time
onboarding_app = <onegov.onboarding.app.OnboardingApp object at 0x7f4b06739250>
temporary_directory = '/tmp/tmpccyo42z0', maildir = '.../tmp/tmpccyo42z0/mails'
redis_url = 'redis://127.0.0.1:31665/0'

    def test_town_create(
        onboarding_app: OnboardingApp,
        temporary_directory: str,
        maildir: str,
        redis_url: str
    ) -> None:
    
        c = Client(onboarding_app)
        a = c.get('/for-towns/1')
    
        a.form['name'] = 'New York0'
        a.form['user'] = 'admin@example.org'
        a.form['color'] = '#ff00ff'
        a.form['user_name'] = 'Major'
        a.form['phone_number'] = '+41791112233'
        a.form['checkbox'].value = True
    
        assert 'Nur Buchstaben sind erlaubt' in a.form.submit()
        a.form['name'] = 'New York'
        a = a.form.submit().follow()
    
        assert 'New York' in a
        assert 'admin@example.org' in a
        assert '#ff00ff' in a
        assert 'new-york.example.org' in a
    
        a = a.form.submit()
    
        assert 'https://new-york.example.org' in a
        assert 'admin@example.org' in a
        assert len(os.listdir(maildir)) == 1
    
        username = 'admin@example.org'
        password = a.pyquery('.product dd:nth-child(4)').text()
    
        scan_morepath_modules(onegov.town6.TownApp)
>       morepath.commit(onegov.town6.TownApp)

.../onegov/onboarding/test_views.py:115: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.............../app/lib/python3.11........./site-packages/dectate/config.py:830: in commit
    configurable.execute()
.............../app/lib/python3.11........./site-packages/dectate/config.py:220: in execute
    self._action_groups[action_class].execute(self)
.............../app/lib/python3.11........./site-packages/dectate/config.py:321: in execute
    action.perform(obj, **kw)
.../onegov/core/directives.py:424: in perform
    app_class.get_layout.register(  # type:ignore[attr-defined]
.............../app/lib/python3.11....../site-packages/reg/dispatch.py:210: in register
    validate_signature(func, self.wrapped_func)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

f = <function Layout.perform.<locals>.layout_for_obj at 0x7f4b0082bec0>
dispatch = <function Framework.get_layout at 0x7f4b1ab94c20>

    def validate_signature(f, dispatch):
        f_arginfo = arginfo(f)
        if f_arginfo is None:
            raise RegistrationError(
                "Cannot register non-callable for dispatch "
                "%r: %r" % (dispatch, f)
            )
        if not same_signature(arginfo(dispatch), f_arginfo):
>           raise RegistrationError(
                "Signature of callable dispatched to (%r) "
                "not that of dispatch (%r)" % (f, dispatch)
            )
E           reg.error.RegistrationError: Signature of callable dispatched to (<function Layout.perform.<locals>.layout_for_obj at 0x7f4b0082bec0>) not that of dispatch (<function Framework.get_layout at 0x7f4b1ab94c20>)

.............../app/lib/python3.11....../site-packages/reg/dispatch.py:244: RegistrationError

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

@Tschuppi81
Copy link
Contributor Author

Tschuppi81 commented Jan 9, 2026

Also i switched the red color in the results to primary and italic

left: previous, right: now
image

@Tschuppi81
Copy link
Contributor Author

Not sure if the breadcrumbs color in search shall be primary or oil, what do you think?

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds breadcrumb navigation to search results for various content types (Topics, News, People, Files, Tickets, Events, Directory Entries, etc.) to provide better context when viewing search results. The implementation includes:

Changes:

  • Renamed PageLayout to TopicLayout throughout the codebase for clarity
  • Added a new get_layout() method to the request object to retrieve layouts for model instances
  • Implemented a layout registry system via a new Layout directive
  • Updated search result templates to display breadcrumbs for various content types
  • Added breadcrumb styling and fixed CSS issues related to z-index stacking
  • Added file ID anchors and highlight styling for targeted files
  • Updated test selectors to use regex anchors for more precise matching

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
tests/onegov/winterthur/test_search.py Updated click selectors to use regex anchors for precise matching
tests/onegov/town6/test_views_directory.py Updated click selectors to use regex anchors for precise matching
tests/onegov/org/test_views_ticket.py Updated click selectors to use regex anchors for precise matching
tests/onegov/org/test_views_directory.py Updated click selectors to use regex anchors for precise matching
tests/onegov/org/test_layout.py Updated imports from PageLayout to TopicLayout
src/onegov/town6/theme/styles/town6.scss Added z-index reset for breadcrumb links
src/onegov/town6/theme/styles/search.scss Added breadcrumb styling and updated search preview styles
src/onegov/town6/theme/styles/files.scss Added highlight and scroll margin for targeted file rows
src/onegov/town6/templates/macros.pt Added breadcrumbs to search result macros, changed p to div tags for consistency
src/onegov/town6/layout.py Renamed PageLayout to TopicLayout, added layout decorators for multiple models, implemented breadcrumbs for GeneralFile and various RIS models
src/onegov/org/views/page.py Updated imports and references from PageLayout to TopicLayout
src/onegov/org/views/editor.py Updated imports and references from PageLayout to TopicLayout
src/onegov/org/request.py Added get_layout() method to retrieve layouts for model instances
src/onegov/org/layout.py Renamed PageLayout to TopicLayout, added FormDefinitionLayout, DirectoryLayout, improved breadcrumbs for various layouts
src/onegov/org/exports/base.py Fixed import to use onegov.org instead of onegov.town6
src/onegov/org/directives.py Added Layout directive for registering layouts to models
src/onegov/org/app.py Added layout directive to OrgApp
src/onegov/agency/views/page.py Updated imports and references from PageLayout to TopicLayout
src/onegov/agency/layout.py Updated imports and class name from PageLayout to TopicLayout

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 1238 to 1242
Link(
self.model.meeting.title,
self.request.link(self.model.meeting)
),
Link(title, self.request.link(self.model))
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The breadcrumbs list includes both self.model.meeting.title (line 1239) and title (line 1242), where title is the same meeting title with an optional date suffix. This creates redundant breadcrumb entries pointing to the same meeting but with different labels. Consider removing the duplicate entry or clarifying the intended breadcrumb structure.

Copilot uses AI. Check for mistakes.
Comment on lines 313 to 320
layout_registry: dict[type, Layout]
) -> str:
return str(self.model)

def perform( # type:ignore[override]
self,
layout: Layout,
layout_registry: dict[type, Layout]
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The type annotation for layout_registry should be dict[type, type] instead of dict[type, Layout] since the layout parameter represents a layout class (type), not an instance of the Layout directive class. The perform method stores layout classes in the registry, not Layout directive instances.

Suggested change
layout_registry: dict[type, Layout]
) -> str:
return str(self.model)
def perform( # type:ignore[override]
self,
layout: Layout,
layout_registry: dict[type, Layout]
layout_registry: dict[type, type[Layout]]
) -> str:
return str(self.model)
def perform( # type:ignore[override]
self,
layout: type[Layout],
layout_registry: dict[type, type[Layout]]

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

I cleaned up the type annotations to still include Layout, but otherwise a correct suggestion.

Comment on lines 150 to 155
.search-preview em {
color: $primary-color !important;
font-style: italic;
font-weight: bold;
text-decoration: underline;
}
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The CSS selector has been changed from .search-results em to .search-preview em, narrowing the scope to only emphasize text within search preview sections. This change may affect emphasis styling for other parts of search results that fall outside the search-preview div.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@BreathingFlesh BreathingFlesh left a comment

Choose a reason for hiding this comment

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

I would give the breadcrumbs a light background so they look more like a separate element

@Tschuppi81
Copy link
Contributor Author

Tschuppi81 commented Jan 13, 2026

Here two examples of how search results look
Screenshot from 2026-01-13 15-35-24

Screenshot from 2026-01-13 15-35-07

…m:OneGov/onegov-cloud into feature/ogc-2880-search-results-with-path
Copy link
Member

@Daverball Daverball left a comment

Choose a reason for hiding this comment

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

Looks good, but we should also register layouts for Org. Other than there's some minor things.

We can probably do a better job for GeneralFile, since only publications will have a simple link to a list of files, we should look at which models have linked to the file and then display the breadcrumbs for each of those models. Performance is definitely a concern when looking for links, so we should probably cache them on the model, just like we cache the access of the linked models. But we can improve handling of general files in a follow-up change, for now I would only display breadcrumbs for publications, we can maybe link to the files management view for logged in users, but I'm not sure it's worth it.

Comment on lines 313 to 320
layout_registry: dict[type, Layout]
) -> str:
return str(self.model)

def perform( # type:ignore[override]
self,
layout: Layout,
layout_registry: dict[type, Layout]
Copy link
Member

Choose a reason for hiding this comment

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

I cleaned up the type annotations to still include Layout, but otherwise a correct suggestion.

Comment on lines 288 to 304
def get_layout(self, model: object) -> Layout | DefaultLayout:
"""
Get the registered layout for a model instance.
"""
layout_registry = self.app.config.layout_registry
model_type = model if isinstance(model, type) else type(model)

layout_class = None
for cls in model_type.mro():
layout_class = layout_registry.get(cls)
if layout_class:
break

if layout_class is None:
layout_class = DefaultLayout

return layout_class(model, self)
Copy link
Member

@Daverball Daverball Jan 14, 2026

Choose a reason for hiding this comment

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

You could probably simplify this by instead relying on a dispatch_method on Framework, which could look something like this:

    @dispatch_method()
    def get_layout_class(self, model: object) -> type[Layout] | None:
        return None

...

@Framework.predicate(Framework.get_layout_class, name="model", default=None, index=ClassIndex)
def model_predicate(self, model: object) -> type:
    return model if isinstance(model, type) else model.__class__

which simplifies get_layout to

    def get_layout(self, model: object) -> Layout:
        """
        Get the registered layout for a model instance.
        """
        layout_class = self.app.get_layout_class(model)

        if layout_class is None:
            layout_class = DefaultLayout

        return layout_class(model, self)

You could also register a predicate_fallback, so get_layout_class returns DefaultLayout if the predicate doesn't match:

@OrgApp.predicate_fallback(OrgApp.get_view, model_predicate)
def model_not_found(self, model: object) -> type[Layout]:
    return DefaultLayout

which simplifies get_layout to

    def get_layout(self, model: object) -> Layout:
        """
        Get the registered layout for a model instance.
        """
        layout_class = self.app.get_layout_class(model)
        assert layout_class is not None
        return layout_class(model, self)

and lets you override the fallback in TownApp with its own DefaultLayout.

You then also no longer need a registry for the LayoutAction, you instead register with the dispatch method:

    def perform(self, layout: type[Layout], app_class: type[Framework]) -> None:
        app_class.get_layout_class.register(layout, model=self.model)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried various things but didn't manage to register properly. Always got the DefaultLayout.
(Even Claude and Gemini got very confused about morepath and reg)

trial branch: #2302

Copy link
Member

Choose a reason for hiding this comment

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

think I got confused about predicates with view, since get_view has an obj argument, and a model predicate, they're different and probably need to be different

So I think you need to change model to obj on get_layout and then also rename the parameter in model_predicate and model_not_found. Basically you can copy this from get_view without the extra request parameter.

You also need to update your directives perform method, so it calls the register method on the dispatch_method. I see you created a custom decorator for testing, but it's possible that that won't work, since there's some very specific magic about how perform on actions is invoked with applications that inherit from one another. This may break if you just register the dispatch immediately with a custom decorator.

You can also test the predicate by checking what app.get_layout.by_predicates(model=MyModel) returns.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, I will still need my directive? I though I will replace the directive by the predicate...

Copy link
Member

Choose a reason for hiding this comment

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

It replaces the registry the directive uses with a dispatch_method not the directive itself. The builtin view directive from morepath also works this way, it doesn't have a registry like the other actions but uses the get_view dispatch_method to register the views.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

We won't need a wrapper object, like they created for views however, since we only want the Layout class itself, we don't care about additional metadata, so you can directly call get_layout.register with the Layout class and the model= predicate, we don't need to support arbitrary predicates.

@Tschuppi81
Copy link
Contributor Author

Thank your for your feedback @BreathingFlesh regarding styling. Latest look

image

Tschuppi81 and others added 6 commits January 15, 2026 11:22
Co-authored-by: David Salvisberg <david.salvisberg@seantis.ch>
Co-authored-by: David Salvisberg <david.salvisberg@seantis.ch>
@Tschuppi81 Tschuppi81 changed the title Adds breadcrumbs to search resutls for Topic and News Search: Add breadcrumbs to search results in order to provide more context Jan 26, 2026
@Tschuppi81
Copy link
Contributor Author

Just pushed a change, still no luck to get the layout registered. Same with the fallback registration.
Any idea? Or shall I go with the Action registry which works fine?

Copy link
Member

@Daverball Daverball left a comment

Choose a reason for hiding this comment

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

There's some confusion about the use of app_class in an Action class, I wonder if that's the reason why it is still not working. I feel like this should be working, since views aren't doing anything more special than we're doing with layouts. It also seems slightly better suited for looking up layouts to me, than a plain dictionary.

Comment on lines 326 to 329
app_class.get_layout_class.register(
model=self.model,
func=lambda app_class, model: obj
)
Copy link
Member

Choose a reason for hiding this comment

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

This does not seem right, I believe this should be simply the following:

Suggested change
app_class.get_layout_class.register(
model=self.model,
func=lambda app_class, model: obj
)
app_class.get_layout_class.register(obj, model=self.model)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Getting a signature issue with app_class.get_layout_class.register(obj, model=self.model)

reg.error.RegistrationError: Signature of callable dispatched to (<class 'onegov.town6.layout.PageLayout'>) not that of dispatch (<function Framework.get_layout_class at 0x7b2f14768e00>)

Copy link
Member

Choose a reason for hiding this comment

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

Oh, you're right I didn't notice that View had a __call__ method that matched get_view, you can still pass the argument positionally though, instead of by name. You should also change app_class to self in both the lambda and the dispatch method. It is a method after all, so the first argument is self, the same goes for the predicate and its fallback, where the first argument is also self, in all instances it's an instance of the current application, i.e. Framework, although you won't need to annotate the type on get_layout_class only the predicate/fallback.

Copy link
Member

@Daverball Daverball Jan 30, 2026

Choose a reason for hiding this comment

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

It might however be worth considering switching from get_layout_class to get_layout and add a request parameter, then Layout.__init__ matches the parameters of get_layout and you get a layout instance for the given model instance and request. So you can directly pass in Layout instead of having to wrap it in a lambda.

It might also be worth considering adding a name predicate so you can overwrite the layout for specific views. That would mean we would no longer have to overwrite Org views in Town6 just to pass the Town6 version of the layout, we just always retrieve the layout using get_layout in the view which will retrieve us the application/view specific layout. But that's a cleanup for later. For now we should just consider prioritizing get_layout over get_layout_class so we have a better API for that.

@Tschuppi81
Copy link
Contributor Author

Tschuppi81 commented Jan 30, 2026

Ah! I needed to the tell the Action class to inject app_class. You were right, Framework was not the App we expected..

class Layout(Action):
    """
    Registers a layout for a model. This is used to show breadcrumbs
    for search results.
    """

    app_class_arg = True

    def __init__(self, model: type) -> None:
        self.model = model
    
    ..

app_class.get_layout.register( # type:ignore[attr-defined]
model=self.model,
request_class=self.request,
func=layout_for_obj
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to pass a layout instance func=obj(self.model, self.request) but it requires a request instance which I don't have, onyl the request class..
@Daverball That was, what you mentioned, right?

Copy link
Member

Choose a reason for hiding this comment

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

func is a replacement for the get_layout function for the given predicate value of model, so it needs to accept the same parameters as get_layout, the idea is to pass obj as func, since Layout.__init__ has the same parameters as get_layout. So you don't call obj here, it only gets called when you call get_layout, with the same parameters you passed into get_layout.

A dispatch_method performs dynamic dispatch using the registered predicates, so it first calls all the predicates to see which version of get_layout needs to be invoked for the given parameters (internally this happens through get_layout.for_predicates(model=obj.__type__) which should then return a Layout class for that model, if it has one or the predicate fallback if it doesn't, subsequently this gets called with the same parameters as get_layout).

Copy link
Member

@Daverball Daverball left a comment

Choose a reason for hiding this comment

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

I think there was some confusion, request is not a predicate it's just a regular parameter on get_layout, so you get back a layout instance for the given obj and request, you don't get a layout class back anymore.

Comment on lines 402 to 429
def __init__(self, model: type, request: CoreRequest) -> None:
self.model = model
self.request = request

def identifier( # type:ignore[override]
self,
app_class: type[Framework]
) -> str:
return str(self.model)

def perform( # type:ignore[override]
self,
obj: type[Layout],
app_class: type[Framework]
) -> None:

def layout_for_obj(
app_self: type[Framework],
model: object,
request: CoreRequest
) -> type[Layout]:
return obj

app_class.get_layout.register( # type:ignore[attr-defined]
model=self.model,
request_class=self.request,
func=layout_for_obj
)
Copy link
Member

@Daverball Daverball Feb 2, 2026

Choose a reason for hiding this comment

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

request is a not a predicate, it's just an additional parameter that gets passed into get_layout, since you need it to create an instance of Layout, so the idea here is to simplify this to the following:

since Layout(obj, request) invokes Layout.__init__(obj, request) which will return a Layout instance for the passed in object and request.

Suggested change
def __init__(self, model: type, request: CoreRequest) -> None:
self.model = model
self.request = request
def identifier( # type:ignore[override]
self,
app_class: type[Framework]
) -> str:
return str(self.model)
def perform( # type:ignore[override]
self,
obj: type[Layout],
app_class: type[Framework]
) -> None:
def layout_for_obj(
app_self: type[Framework],
model: object,
request: CoreRequest
) -> type[Layout]:
return obj
app_class.get_layout.register( # type:ignore[attr-defined]
model=self.model,
request_class=self.request,
func=layout_for_obj
)
def __init__(self, model: type) -> None:
self.model = model
def identifier( # type:ignore[override]
self,
app_class: type[Framework]
) -> str:
return str(self.model)
def perform( # type:ignore[override]
self,
obj: type[Layout],
app_class: type[Framework]
) -> None:
app_class.get_layout.register(obj, model=self.model)

Comment on lines +81 to +87
@TownApp.predicate_fallback(TownApp.get_layout, layout_predicate)
def layout_not_found(self: type[TownApp], obj: object) -> type[Layout]:
# circular import
from onegov.town6.layout import DefaultLayout
return DefaultLayout


Copy link
Member

Choose a reason for hiding this comment

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

With the changed semantics you can decorate the original definition of DefaultLayout with @TownApp.predicate_fallback(TownApp.get_layout, layout_predicate), just like you directly decorate the other layouts for their respective model. This also gets rid of the circular import.

Copy link
Member

Choose a reason for hiding this comment

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

You will also need to do the same for OrgApp and its own DefaultLayout.

Copy link
Member

@Daverball Daverball Feb 3, 2026

Choose a reason for hiding this comment

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

Looks like it's not going to be as simple after all. We could probably do something with a custom __call__ on a metaclass that discards the first argument if it is an instance of Framework, so we could directly use Layout classes as valid implementations, without having to change the default signature for __init__. But it's probably a bit too magical, may not work with the kind of introspection morepath uses and not worth the additional effort, to make introspection work, I'd still move the registration of the fallback to where the layouts are defined, so you don't need a circular import.

It would then look something like:

@TownApp.predicate_fallback(TownApp.get_layout, layout_predicate)
def layout_not_found(self: TownApp, obj: object, request: TownRequest) -> Layout:
    return DefaultLayout(obj, request)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, will move it to layouts

Copy link
Member

@Daverball Daverball left a comment

Choose a reason for hiding this comment

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

Looks like I forgot, that the first parameter to the dispatch_method for the app instance is required for all implementations, we still want the request parameter though, just not as a predicate and we want to return a layout instance, not a class.

Comment on lines +1561 to +1579
@dispatch_method()
def get_layout(
self,
obj: object,
) -> type[Layout] | None:
return None


@Framework.predicate(
Framework.get_layout,
name='model',
default=None,
index=ClassIndex
)
def layout_predicate(
self: type[Framework],
obj: object,
) -> type[Layout]:
return obj.__class__
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
@dispatch_method()
def get_layout(
self,
obj: object,
) -> type[Layout] | None:
return None
@Framework.predicate(
Framework.get_layout,
name='model',
default=None,
index=ClassIndex
)
def layout_predicate(
self: type[Framework],
obj: object,
) -> type[Layout]:
return obj.__class__
@dispatch_method()
def get_layout(
self,
obj: object,
request: CoreRequest
) -> type[Layout] | None:
return None
@Framework.predicate(
Framework.get_layout,
name='model',
default=None,
index=ClassIndex
)
def layout_predicate(
self: type[Framework],
obj: object,
request: CoreRequest
) -> type[Layout]:
return obj.__class__

Comment on lines +411 to +421
def perform( # type:ignore[override]
self,
obj: type[Layout],
app_class: type[Framework]
) -> None:

layout_obj = obj
# `lambda self, obj` is required to match the signature
app_class.get_layout.register(
lambda self, obj: layout_obj,
model=self.model)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
def perform( # type:ignore[override]
self,
obj: type[Layout],
app_class: type[Framework]
) -> None:
layout_obj = obj
# `lambda self, obj` is required to match the signature
app_class.get_layout.register(
lambda self, obj: layout_obj,
model=self.model)
def perform( # type:ignore[override]
self,
obj: type[Layout],
app_class: type[Framework]
) -> None:
layout_class = obj
# `lambda self, obj` is required to match the signature
app_class.get_layout.register(
lambda app, obj, request: layout_class(obj, request),
model=self.model)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like the idea, but need to keep the signature and if I'd pass the TownRequest or OrgRequest class to the Layout, I only have the class not the instance...

Copy link
Member

Choose a reason for hiding this comment

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

I promise you this will work, this is exactly the same way get_view is implemented, it also takes a second request parameter.

Copy link
Member

Choose a reason for hiding this comment

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

You will need to adapt OrgRequest.get_layout and the code that uses the returned layout for the breadcrumbs, but it's an overall minor change.

Copy link
Member

Choose a reason for hiding this comment

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

Remember that predicates are different from regular parameters, this is not a predicate, so you don't need to pass it in when you register the layout, it gets passed in when you call get_layout. Only predicates need to be passed eagerly and the only predicate we have currently is model, this doesn't change.

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