简体   繁体   中英

in Celery/Django : cannot find reference 'control' in celery.task.control

I'm trying to use celery in my project. when I use from celery.task.control import revoke the PyCharm highlight control and warn me cannot find reference 'control' in __init__.py and also PyCharm adds broken line under revoke and warn me Unresolved reference revoke .

But when I run the project, celery is working great without any problem with calling tasks or revoking them. My question is why PyCharm warns me and is it possible in future any problem happen about that?

celery.py:

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hamclassy.settings')

app = Celery('hamclassy')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()

project/__init__.py:

from __future__ import absolute_import, unicode_literals

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app

__all__ = ['celery_app']

This typically happens when you use one Python virtual environment (or just local Python) in your PyCharm, and another Python environment for your Celery worker. If you properly install Celery in the environment used by PyCharm you will not see that warning.

As long as the environment where you want to run your Celery worker in has Celery properly installed you will be fine, and you may ignore the PyCharm warning, but I recommend you install Celery in your PyCharm project's environment too to enjoy the benefits of PyCharm code analysis, etc...

The 'control' module is located in celery.app not celery.task . Importing 'revoke' the way that you have it set up will not work.

I stumbled upon the same thing today and also got curious.

Let's first prove that it works:

$ mkdir tmp
$ cd tmp
$ python -m venv env
$ source env/bin/activate
$ pip install celery==4.4.7
$ python
Python 3.10.5 ...
Type "help", "copyright", "credits" or "license" for more information.
>>> from celery.task.control import revoke
>>> from celery.task.control import foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'foo' from 'control' (unknown location)

So we can clearly import revoke from celery.task.control in celery 4.4.7. It works.

Though if you go looking for the definition of revoke() , you will not find it in celery/task ! But the import works. What are we importing then?

Using this info it's possible check what we have imported. Continuing the session above:

>>> import inspect
>>> print(inspect.getsourcefile(revoke))
.../lib/python3.10/site-packages/celery/app/control.py

Aha, so revoke() is defined in celery/app/control.py .

But we imported celery.task.control . How can it resolve to celery.app.control ?

As celery/task/control.py and celery/task/control don't exist, it has to happen in celery/task/__init__.py . I'm not completely certain how it works, but I suspect LazyModule, Proxy and recreate_module are involved. Dig into this file if you want to know more.

To answer your question then, PyCharm likely adds a broken line under revoke and warns you Unresolved reference revoke because it can't follow the non-standard import setup celery has devised. My pylint can't follow it either.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM