Import a package that does not exist

I had never seen an import problem before. I removed the directory from site-packages and the corresponding package is still being imported.

 python2 > import google > print(google.__path__) ['/home/bamboo/.local/lib/python2.7/site-packages/google'] 

However, this directory does not actually exist.

 ls: cannot access /home/bamboo/.local/lib/python2.7/site-packages/google: No such file or directory 

I deleted everything that I know that it is connected with it, but still there must be something hanging.

Digging even deeper, I tried to restart google .

 python2 > import google; > reload(google); ImportError: No module named google 

Thus, it is obvious that it recognizes that it is rebooted.

By checking sys.modules you get

 python2 > import sys > print(sys.modules) {'google': <module 'google' (built-in)>, 'copy_reg': <module 'copy_reg' from '/usr/lib/python2.7/copy_reg.pyc'> ... 

which indicates that google seems to be inline.

Motivation note: Typically, such a problem would be a strange but not an indicative traffic jam. The problem for me is that the google package is masking another package with the same name.

+5
source share
1 answer

tl, dr: use pip to completely remove Google packages.

There are two problems here:

  • strange google package import / reload behavior
  • uninstall google package

import / reload

I can reproduce the import / reload behavior by installing (google) protobuf (many google packages will behave the same way).

 $ mktmpenv -p $(which python2) ... $ python --version Python 2.7.13 $ pip install protobuf ... Installing collected packages: six, protobuf Successfully installed protobuf-3.5.1 six-1.11.0 >>> import google >>> print google.__path__ ['~/virtual-envs/tmp-66cd9b4d01a8dec6/lib/python2.7/site-packages/google'] >>> import sys >>> print sys.modules['google'] <module 'google' (built-in)> >>> reload(google) Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named google 

I suspect that what is happening here is that Google prefers all Google packages to be installed in the same google package, but this package is not intended to be imported, and therefore, unexpected restart behavior. However, importing subpackages by name works as expected:

 >>> import protobuf Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named protobuf >>> from google import protobuf >>> protobuf.__path__ ['~/virtual-envs/tmp-66cd9b4d01a8dec6/lib/python2.7/site-packages/google/protobuf'] >>> reload(protobuf) <module 'google.protobuf' from '~/virtual-envs/tmp-66cd9b4d01a8dec6/lib/python2.7/site-packages/google/protobuf/__init__.pyc'> >>> 

Uninstall google package

The question says:

I removed the directory from the site packages, and the corresponding package is still imported.

This can also be reproduced:

 ($ rm -rf ~/virtual-envs/tmp-66cd9b4d01a8dec6/lib/python2.7/site-packages/google $ python >>> import google >>> print google.__path__ ['~/virtual-envs/tmp-66cd9b4d01a8dec6/lib/python2.7/site-packages/google'] >>> 

The problem is that simply removing the google directory and its contents is not enough to completely remove all Google packages.

The site-packages directory still contains the protobuf-3.5.1-py2.7-nspkg.pth that contains this code (it is split into separate lines for easy reading, the original is a single line of comma-separated statements):

 import sys, types, os has_mfs = sys.version_info > (3, 5) p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('google',)) importlib = has_mfs and __import__('importlib.util') has_mfs and __import__('importlib.machinery') m = has_mfs and sys.modules.setdefault('google', importlib.util.module_from_spec(importlib.machinery.PathFinder.find_spec('google', [os.path.dirname(p)]))) m = m or sys.modules.setdefault('google', types.ModuleType('google')) mp = (m or []) and m.__dict__.setdefault('__path__',[]) (p not in mp) and mp.append(p) 

Line

m = m or sys.modules.setdefault('google', types.ModuleType('google'))

creates a google module in sys.modules if it does not already exist, so the google module is imported even after the directory is deleted.

The correct way to remove google module is to remove google packages using pip :

pip uninstall protobuf

If pip not available in the build environment, this is a case of identifying any related files and folders ( *dist-info/ , *.pth ) in site packages and deleting them manually.

+3
source

Source: https://habr.com/ru/post/1274510/


All Articles