dify - 💡(How to fix) Fix change some ABC to Protocol

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

Rename to something like VariableTruncatorProtocol or keep BaseTruncator as a protocol if churn matters. Existing tests that call abstract placeholder methods, e.g. tests/unit_tests/ services/test_variable_truncator_additional.py:21, should be deleted because that behavior is an artifact of ABC, not a useful contract.

Fix Action

Fix / Workaround

1. Convert BaseQueueDispatcher to a small Protocol

FilePath: services/workflow/queue_dispatcher.py:25

This is a pure behavior contract: get_queue_name() and get_priority() only. There is no constructor, state, shared method, or runtime invariant. QueueDispatcherManager.get_dispatcher() only needs “an object with those two methods”, so a structural protocol fits better than an ABC.

RAW_BUFFERClick to expand / collapse

find by codex

1. Convert BaseQueueDispatcher to a small Protocol

FilePath: services/workflow/queue_dispatcher.py:25

Explanation

This is a pure behavior contract: get_queue_name() and get_priority() only. There is no constructor, state, shared method, or runtime invariant. QueueDispatcherManager.get_dispatcher() only needs “an object with those two methods”, so a structural protocol fits better than an ABC.

Suggested Fix

Use class QueueDispatcher(Protocol) and update return annotations. The current abstract-instantiation test at tests/unit_tests/services/workflow/test_queue_dispatcher.py:38 should be removed or replaced with behavior tests.

———

2. Convert BaseTruncator to Protocol

FilePath: services/variable_truncator.py:69

Explanation

BaseTruncator is only used as an injectable capability in places like core/app/apps/common/workflow_response_converter.py:121. Both VariableTruncator and DummyVariableTruncator just need to satisfy truncate() and truncate_variable_mapping(). No shared code lives in the base.

Suggested Fix

Rename to something like VariableTruncatorProtocol or keep BaseTruncator as a protocol if churn matters. Existing tests that call abstract placeholder methods, e.g. tests/unit_tests/ services/test_variable_truncator_additional.py:21, should be deleted because that behavior is an artifact of ABC, not a useful contract.

———

3. Convert WorkflowPauseEntity to Protocol

FilePath: repositories/entities/workflow_pause.py:16

Explanation

This file already describes a storage-independent domain shape. Callers mostly need properties and methods, not inheritance. The SQLAlchemy private implementation currently subclasses it, but service/repository signatures would work cleanly with a protocol.

Suggested Fix

Use class WorkflowPauseEntity(Protocol). This would make test fakes lighter, especially the many _FakePauseEntity classes under workflow pause tests.

———

4. Convert MessagesCleanPolicy to Protocol

FilePath: services/retention/conversation/messages_clean_policy.py:22

Explanation

The policy abstraction is a single method: filter_message_ids(...). The concrete policies carry their own dependencies and state, and the service only needs the method shape.

Suggested Fix

Replace the ABC with a protocol. Keep concrete policy classes unchanged except removing inheritance if desired.

———

5. Convert RecommendAppRetrievalBase to Protocol

FilePath: services/recommend_app/recommend_app_base.py:4

Explanation

This is a pure retrieval interface with no shared behavior. The factory returns type[RecommendAppRetrievalBase] at services/recommend_app/recommend_app_factory.py:10, which could become a protocol-backed constructor type.

Suggested Fix

Use a protocol for the instance contract. If the factory returns classes, define a constructor protocol only if type checking needs it.

———

6. Convert PipelineTemplateRetrievalBase to Protocol, but update tests first

FilePath: services/rag_pipeline/pipeline_template/pipeline_template_base.py:5

Explanation

Like recommend-app retrieval, this is a pure three-method interface. The only reason to keep ABC is current tests asserting abstractmethods, e.g. tests/unit_tests/services/ rag_pipeline/pipeline_template/test_pipeline_template_base.py:33. Those tests are testing Python ABC mechanics, not product behavior.

Suggested Fix

Change tests to verify factory selection and retrieval behavior, then convert the base to Protocol.

———

7. Consider converting AppContext to Protocol

FilePath: context/execution_context.py:18

Explanation

ExecutionContext stores app_context: AppContext | None and only calls enter(), get_config(), and get_extension(). There is already an adjacent protocol style in IExecutionContext at context/execution_context.py:42, so converting AppContext would make this module more consistent.

Suggested Fix

Convert only if you do not rely on “cannot instantiate base class” tests. FlaskAppContext at context/flask_app_context.py:16 can then stop inheriting and just satisfy the protocol structurally.

🟢 Nits (Optional)

1. BaseStorage is tempting, but I would not make it the first conversion

FilePath: extensions/storage/base_storage.py:7

Explanation

It is interface-like, but many storage backends explicitly inherit it, and scan() provides a default unsupported implementation. It can become a protocol later, but the churn across storage providers is higher than the service-layer candidates above.

Suggested Fix

If touched, split into Storage(Protocol) for consumers and keep an optional mixin/base for default scan() behavior.

✅ What's Good

  • Keep ABC for classes with shared state or template methods: DocumentTaskProxyBase, AppQueueManager, AppGenerateResponseConverter, Tool, ProviderCredentialsCache, BaseIndexProcessor.
  • The best first PR would be small: BaseTruncator or MessagesCleanPolicy. They have clear consumers and low architectural blast radius.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING