"django_components.component" does not explicitly export attribute "register"
I have a component like this
from typing import Dict, Any
from django_components import component
from server.example.models import Example
@component.register('example')
class ExampleComponent(component.Component):
template_name = 'example/template.html'
def get_context_data(self, instance: Example) -> Dict[str, Any]:
return {
'instance': instance,
}
When running mypy I get the following error: error: Module "django_components.component" does not explicitly export attribute "register" [attr-defined]
@thacoon How would we fix this, and are you open to writing a PR?
Looking at this thread, I guess a temporary workaround could be to either:
- Use
rom django_components.component_registry import registry - Set in mypy.ini
mplicit_reexport = True
What would be a proper fix? @thacoon can you share your mypy config?
@JuroOravec my latest configuration is:
[mypy]
# Mypy configuration:
# https://mypy.readthedocs.io/en/latest/config_file.html
enable_error_code =
truthy-bool,
truthy-iterable,
redundant-expr,
unused-awaitable,
ignore-without-code,
possibly-undefined,
redundant-self,
explicit_package_bases = true
ignore_missing_imports = true
strict = true
warn_unreachable = true
plugins =
mypy_django_plugin.main
[mypy-server.apps.*.migrations.*]
# Django migrations should not produce any errors:
ignore_errors = true
[mypy.plugins.django-stubs]
# Docs: https://github.com/typeddjango/django-stubs
django_settings_module = config.settings
strict_settings = false
I think the problem this mypy error is trying to point us at, is that we rely on the component module importing register as an API, but it's all implicit. So if we would refactor the module, and accidentally remove that import, we wouldn't notice that the API broke.
A simple way to explicitly define the public API is specifying all, and list all the symbols we export. Isn't that the simplest solution here?
@EmilStenstrom So we want to define __all__ inside ~src/__init__.py~ src/component.py, is that correct?
@thacoon I wasn't able to get the same error in my project, but it might be because there I'm on django_components 0.66 and mypy 1.7.0. What versions are you on?
Could you possibly test the solution below to check if it solves the issue? In your python packages folder, navigate to django_components/components.py, and on line 22 or 23, change
from django_components.component_registry import AlreadyRegistered, ComponentRegistry, NotRegistered, register # NOQA
to
from django_components.component_registry import (
AlreadyRegistered as AlreadyRegistered,
ComponentRegistry as ComponentRegistry,
NotRegistered as NotRegistered,
register as register,
)
And then run mypy.
@thacoon I wasn't able to get the same error in my project, but it might be because there I'm on django_components 0.66 and mypy 1.7.0. What versions are you on?
Could you possibly test the solution below to check if it solves the issue? In your python packages folder, navigate to
django_components/components.py, and on line 22 or 23, changefrom django_components.component_registry import AlreadyRegistered, ComponentRegistry, NotRegistered, register # NOQAto
from django_components.component_registry import ( AlreadyRegistered as AlreadyRegistered, ComponentRegistry as ComponentRegistry, NotRegistered as NotRegistered, register as register, )And then run mypy.
I can confirm that this works with:
mypy==1.7.1django_components==0.74
@mikucz Excellent! Mind writing up a PR as well? Should be a good first contribution, don't you think? :)
@mikucz Excellent! Mind writing up a PR as well? Should be a good first contribution, don't you think? :)
@EmilStenstrom PR as requested: https://github.com/EmilStenstrom/django-components/pull/499 :)
@mikucz Thanks again for the contribution! This has now been release as part of https://github.com/EmilStenstrom/django-components/releases/tag/0.75