There seems to be a problem either with detecting Python3 namespace packages properly or with separation of Python3 absolute imports vs relative imports (or the combination of both) leading to false positives when a module, not at the toplevel imports a toplevel library of the same name.
There is a Python library named urwid which makes curses (screen-based, text-based user interfaces) easier to program. My application has plugins for different UIs. The plugin for urwid is named, urwid. So if my project and the urwid library were both installed in the same directory structure it would look like this:
Now, I want plugins to be installable in different directories. For instance, stellarmagnate might come pre-installed on a Linux distro via rpm packages in /usr/lib/python3.8/site-packages/stellarmagnate. The user might then install a new ui plugin via pip install stellarmagnate-ui-kivy --user to ~/.local/lib/python3.8/site-packages/stellarmagnate.
To achieve that I use Python's Implicit namespace packages: https://www.python.org/dev/peps/pep-0420/ Which tell Python to allow importing non-conflicting python modules from multiple locations on the PYTHONPATH. As you can see in the directory structure above, only two directories have __init__.py files. The other directories are implicit namespace packages. So when stellarmagnate.ui.urwid is imported, Python will look in /usr/lib/python3.8/site-packages/stellarmagnate/ui/ for urwid. If it's not there, it will look in ~/.local/lib/python3.8/site-packages/stellarmagnate/ui/ for urwid, and so forth along all of the PYTHONPATH directories.
Specifics:
My urwid plugin imports the urwid library using this code in stellarmagnate/ui/urwid/__init__.py:
import urwid
lgtm is flagging this as a python module importing itself. That would be true in Python2 (unless from __future__ import absolute_imports was specified, which gives Python2 the same behaviour as Python3) but in Python3, it is importing the toplevel urwid module from directly in the site-packages directory. If the plugin was importing itself it would either have to use a relative import:
from . import urwid
or it would have to be directly on the PYTHONPATH. (ie: if site-packages/urwid/__init__.py had a import urwid, then that would be an illegal self import.)
I'm not sure if relative imports or implicit namespaces are confusing the analysis but one or the other seems likely.
Description of the false positive
Summary:
There seems to be a problem either with detecting Python3 namespace packages properly or with separation of Python3 absolute imports vs relative imports (or the combination of both) leading to false positives when a module, not at the toplevel imports a toplevel library of the same name.
URL to the alert on the project page on LGTM.com https://lgtm.com/projects/g/abadger/stellarmagnate/snapshot/fd6bd899321e58db828afcb0622275c867a6fa1e/files/magnate/ui/urwid/__init__.py?sort=name&dir=ASC&mode=heatmap#xba047dafaec728fd:1
Background:
There is a Python library named urwid which makes curses (screen-based, text-based user interfaces) easier to program. My application has plugins for different UIs. The plugin for urwid is named, urwid. So if my project and the urwid library were both installed in the same directory structure it would look like this:
Now, I want plugins to be installable in different directories. For instance, stellarmagnate might come pre-installed on a Linux distro via rpm packages in
/usr/lib/python3.8/site-packages/stellarmagnate
. The user might then install a new ui plugin viapip install stellarmagnate-ui-kivy --user
to~/.local/lib/python3.8/site-packages/stellarmagnate
.To achieve that I use Python's Implicit namespace packages: https://www.python.org/dev/peps/pep-0420/ Which tell Python to allow importing non-conflicting python modules from multiple locations on the PYTHONPATH. As you can see in the directory structure above, only two directories have
__init__.py
files. The other directories are implicit namespace packages. So whenstellarmagnate.ui.urwid
is imported, Python will look in/usr/lib/python3.8/site-packages/stellarmagnate/ui/
forurwid
. If it's not there, it will look in~/.local/lib/python3.8/site-packages/stellarmagnate/ui/
forurwid
, and so forth along all of the PYTHONPATH directories.Specifics: My urwid plugin imports the urwid library using this code in
stellarmagnate/ui/urwid/__init__.py
:lgtm is flagging this as a python module importing itself. That would be true in Python2 (unless
from __future__ import absolute_imports
was specified, which gives Python2 the same behaviour as Python3) but in Python3, it is importing the toplevelurwid
module from directly in the site-packages directory. If the plugin was importing itself it would either have to use a relative import:or it would have to be directly on the PYTHONPATH. (ie: if
site-packages/urwid/__init__.py
had aimport urwid
, then that would be an illegal self import.)I'm not sure if relative imports or implicit namespaces are confusing the analysis but one or the other seems likely.