Search code examples
pycharm

PyCharm: Why does `audioop` get prefered?


Why does audioop get prefered, if I want to import reverse()?

My code contains from django.urls import reverse already in many files.

Why does PyCharm not look my other files and then make the currently second option the first one?

I have never used the module audioop in my whole life.

pycharm-import-reverse-django


Solution

  • Why does audioop get preferred, if I want to import reverse()?

    audioop is a built-in module, so its stub file audioop.py exists in PyCharm's python_stubs.

    PyCharm simply lists the Auto Import suggestions in alphabetical order.
    PyCharm lists the Auto Import suggestions by category, in alphabetical order within each one:

    1. known references from imports in the current file (more about this in its own section below)
    2. first party modules
    3. built-in modules ← audioop belongs here
    4. third party modules ← django belongs here
    5. pip._vendor modules

    My code contains from django.urls import reverse already in many files.

    Why does PyCharm not look my other files and then make the currently second option the first one?

    Such an inference mechanism is simply not implemented in PyCharm.

    PyCharm does prioritise known references from imports in the current file, with some caveats (more about this in its own section below).

    Workaround

    I have never used the module audioop in my whole life.

    You can safely delete the file, or just change the file extension (e.g. audioop.txt).

    It will be regenerated when you reopen the project in PyCharm.

    Known references from imports in the current file

    PyCharm prioritises known references from imports in the current file, with some caveats.

    For example, if you have from django.urls.base import get_script_prefix in that file, then PyCharm would suggest reverse() from django.urls.base (which django.urls exposes) since it knows reverse is in django.urls.base.

    Caveat: Import references aren't suggested.
    For example, having from django.urls import path (if you're working in urls.py) doesn't suggest reverse() from django.urls because reverse is an import reference (i.e. jumping to django.urls.reverse would bring you straight to django.urls.base.reverse, since django/urls/__init__.py simply imported reverse from django.urls.base).

    Workaround: Alias the import, and then assign that to the original name.
    For example, modify the import in django/urls/__init__.py from reverse to reverse as _reverse and then define the variable reverse = _reverse.

    • Caveat of this workaround: PyCharm hints this as a variable instead of a function.

      Workaround: Wrap the function.

      def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
          return _reverse(viewname, urlconf=urlconf, args=args, kwargs=kwargs, current_app=current_app)