I have a problem that I can't solve since days. I created a python module "medux_timetracker" packaged as GDAPS plugin, details below, using an entry point. But the entry point is not recognized - and I'm stuck. The module is installed using flit install --symlink.
from within the medux-timetracker directory, using the venv of the main project.
pyproject.toml
[build-system]
requires = ["flit_core >=3.2,<4"]
build-backend = "flit_core.buildapi"
[project]
name = "medux_timetracker"
# ...
[tool.flit.module]
name="medux.plugins.timetracker:apps.TimeTrackerConfig"
# medux.plugins are namespace modules.
[project.entry-points."medux.plugins"]
timetracker = "medux.plugins.timetracker"
The class TimeTrackerConfig
in this module is basically a Django app, inheriting AppConfig
.
# settings.py
INSTALLED_APPS = [
# ...
]
INSTALLED_APPS += PluginManager.find_plugins("medux.plugins")
Here the installed apps are dynamically appended by the PluginManager's method which is this (the relevant part where GDAPS/Django loads the entry_point):
@classmethod
def find_plugins(cls, group: str) -> List[str]:
"""Finds plugins from setuptools entry points.
This function is supposed to be called in settings.py after the
INSTALLED_APPS variable....
:param group: a dotted path where to find plugin apps. This is used as
'group' for setuptools' entry points.
:returns: A list of dotted app_names, which can be appended to
INSTALLED_APPS.
"""
# ...
cls.group = group # ="medux.plugins"
installed_plugin_apps = []
# here iter_entry_points returns nothing, so the for loop does never execute:
for entry_point in iter_entry_points(group=group, name=None):
appname = entry_point.module_name
if entry_point.attrs:
appname += "." + ".".join(entry_point.attrs)
installed_plugin_apps.append(appname)
logger.info("Found plugin '{}'.".format(appname))
return installed_plugin_apps
The error message when I start the Django server:
File "/home/christian/Projekte/medux/.venv/lib/python3.10/site-packages/django/apps/config.py", line 193, in create
import_module(entry)
File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1004, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'medux.plugins.timetracker'
So, GDAPS finds the entry point from pyproject.toml
, "medux.plugins.timetracker" is appended to INSTALLED_APPS correctly, but this module is not found. I suppose it's a PYTHONPATH problem, but can't find out why.
in the venv, under.../lib/python3.10/site-packages, I have:
medux/
plugins/
timetracker -> /home/christian/Projekte/medux-timetracker # symlink
medux_timetracker-0.0.1.dist-info/
direct_url.json
entry_points.txt
INSTALLER
METADATA
RECORD
REQUESTED
So the symlink to the package is there. I don't know further.
AAARGH.Why is it always the same? after searching for days, I post on stackoverflow, and one hour later I find the answer by accident.
So at least, if anyone reads this, maybe it helps to know how I solved it:
plugin package:
medux/
plugins/
timetracker/
__init__.py
apps.py
...
main package:
...
medux/
__init__.py
plugins/
core/
contrib/
...
So in the main package medux
was a real package (no namespace package), and import medux.plugins
would import the main packages module, overriding the plugins', and medux.plugins.timetracker
was never found.
launching a python interpreter from another directory worked and brought me to the solution:
I just deleted the init .py in the main repo, hence making a namespace package of medux here too, and it worked at once.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.