classification
Title: distutils.sysconfig.get_python_lib behaves incorrectly when pip cache is enabled
Type: behavior Stage: resolved
Components: Distutils Versions: Python 3.7
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: dstufft, eric.araujo, sabakauser, steve.dower, xtreak
Priority: normal Keywords:

Created on 2019-04-16 09:22 by sabakauser, last changed 2021-02-03 18:16 by steve.dower. This issue is now closed.

Messages (7)
msg340324 - (view) Author: Saba Kauser (sabakauser) Date: 2019-04-16 09:22
Hi,
I have added a post install class that's working fine when I do "pip install ibm_db" on MAC. However, when I use the python/pip from anaconda3(python 3.7), the same pip is not executing the post install script.
Can some one please take a look at assist.
The class can be seen at:
https://github.com/ibmdb/python-ibmdb/blob/master/IBM_DB/ibm_db/setup.py#L52

Post install, I am expecting following output:
BLR-D-MACOS03:site-packages skauser$ otool -L ibm_db.cpython-37m-darwin.so
ibm_db.cpython-37m-darwin.so:
        @loader_path/clidriver/lib/libdb2.dylib (compatibility version 0.0.0, current version 0.0.0)

When executing from Anaconda, the name of libdb2.dylib is unchanged.

I would also like to know how can I verbose the print/log statements of my setup.py via pip  install.
msg340325 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2019-04-16 09:41
Anacond and ibm_db are not part of CPython distribution. Can you please add a script and explain over how it's a bug with CPython? There are also previous reports when searching for "ibm_db" and I am not sure if these are bugs with CPython too.

https://bugs.python.org/issue?%40columns=id%2Cactivity%2Ctitle%2Ccreator%2Cassignee%2Cstatus%2Ctype&%40sort=-activity&%40filter=status&%40action=searchid&ignore=file%3Acontent&%40search_text=ibm_db&submit=search&status=-1%2C1%2C2%2C3
msg340327 - (view) Author: Saba Kauser (sabakauser) Date: 2019-04-16 10:01
Thanks Karthikeyan.

The behavior is specific to anaconda when I use the python/pip that comes with it. When I use the pip from anaconda, 
e.g:/Users/skauser/anaconda3/bin/pip

pip install ibm_db
Installation is success,but when I import ibm_db, I get this error

import ibm_db
>>> import ibm_db
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dlopen(/Users/skauser/anaconda3/lib/python3.7/site-packages/ibm_db.cpython-37m-darwin.so, 2): Library not loaded: libdb2.dylib
  Referenced from: /Users/skauser/anaconda3/lib/python3.7/site-packages/ibm_db.cpython-37m-darwin.so
  Reason: image not found

Reason being, the post install script of my setup.py is not executed and hence following command did not run post install .

for so in glob.glob(get_python_lib()+r'/ibm_db*.so'):
os.system("install_name_tool -change libdb2.dylib {}/lib/libdb2.dylib {}".format(clipath, so))

Can be seen at 
https://github.com/ibmdb/python-ibmdb/blob/master/IBM_DB/ibm_db/setup.py#L58

However, when I use the standalone python installation that is outside of anaconda distribution, pip install correctly runs the post install script ibm_db's setup.py.

/Library/Frameworks/Python.framework/Versions/3.7/bin/python3
Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 03:13:28)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ibm_db
>>

The error Reason: image not found is specific to MAC due to its security setting and I have added a workaround that is expected to work with pip install. However, it does not seem to work.
msg340478 - (view) Author: Saba Kauser (sabakauser) Date: 2019-04-18 09:43
I was able to determine the reason. 
When running through anaconda, the pip copies ibm_db.so to site-packages path. However, as logged in user, install_name_tool fails with permission denied error.

BLR-D-MACOS03:site-packages skauser$ install_name_tool -change @loader_path/clidriver/lib/libdb2.dylib libdb2.dylib ibm_db.cpython-37m-darwin.so
error: /Library/Developer/CommandLineTools/usr/bin/install_name_tool: can't open input file: ibm_db.cpython-37m-darwin.so for writing (Permission denied)
error: /Library/Developer/CommandLineTools/usr/bin/install_name_tool: can't lseek to offset: 0 in file: ibm_db.cpython-37m-darwin.so for writing (Bad file descriptor)
error: /Library/Developer/CommandLineTools/usr/bin/install_name_tool: can't write new headers in file: ibm_db.cpython-37m-darwin.so (Bad file descriptor)
error: /Library/Developer/CommandLineTools/usr/bin/install_name_tool: can't close written on input file: ibm_db.cpython-37m-darwin.so (Bad file descriptor)
BLR-D-MACOS03:site-packages skauser$ sudo install_name_tool -change @loader_path/clidriver/lib/libdb2.dylib libdb2.dylib ibm_db.cpython-37m-darwin.so

Even if i do "sudo pip install ibm_db", although the package is copied to site-packages, install_name_tool fails with error.
However, if build the source via pip as :

cd  /Users/skauser/python-ibmdb/IBM_DB/ibm_db
sudo pip install .

install_name_tool is able to execute on ibm_db*.so.

Do you have any idea why would the permission problem occur only if I do pip install from pypi and not from source?
msg340640 - (view) Author: Saba Kauser (sabakauser) Date: 2019-04-22 05:42
I have debugged this further.
The problem seems be happening due to usage of get_python_lib().

e.g:
if('darwin' in sys.platform):
    class PostInstall(install):
        """ Post installation - run install_name_tool on Darwin """
        def run(self):
            install.run(self)
            clipath = os.getenv('IBM_DB_HOME', '@loader_path/clidriver')
            print("in PostInstall with {}".format(clipath))
            for so in glob.glob(get_python_lib()+r'/ibm_db*.so'):
                os.system("install_name_tool -change libdb2.dylib {}/lib/libdb2.dylib {}".format(clipath, so))

cmd_class = dict(install = PostInstall)

The get_python_lib() returns following path and hence my script is never able to fetch the matching lib name.
example output of get_python_lib() usage:
    /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Users/skauser/anaconda3/lib/python3.7/site-packages/CHANGES
    /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Users/skauser/anaconda3/lib/python3.7/site-packages/LICENSE
    /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Users/skauser/anaconda3/lib/python3.7/site-packages/README.md
    /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Users/skauser/anaconda3/lib/python3.7/site-packages/config.py.sample


I have both anaconda and standalone python installations and get_python_lib() seem to get confused with different paths.
It sometimes returns the duplicate path as well:
e.g: 
    /Users/skauser/anaconda3/lib/python3.7/site-packages/Users/skauser/anaconda3/lib/python3.7/site-packages/CHANGES
    /Users/skauser/anaconda3/lib/python3.7/site-packages/Users/skauser/anaconda3/lib/python3.7/site-packages/LICENSE
    /Users/skauser/anaconda3/lib/python3.7/site-packages/Users/skauser/anaconda3/lib/python3.7/site-packages/README.md
    /Users/skauser/anaconda3/lib/python3.7/site-packages/Users/skauser/anaconda3/lib/python3.7/site-packages/config.py.sample

Above examples are taken from one usage of get_python_lib() for copying certain data files while installation to site-packages. 
My strong belief is that, its the same problem with the post-install script as well.

Why is get_python_lib() behavior not consistent? 
What are the other alternatives to get the current site-package path for the running installation?

When I disable cache of pip and install, get_python_lib() path as retrieved while install behaves correctly.
e.g: pip --no-cache-dir install ibm_db

Kindly help! This is blocking production of many users.
msg340879 - (view) Author: Saba Kauser (sabakauser) Date: 2019-04-26 03:26
Experts, please help.
get_python_lib() is behaving strangely and I have detailed the problem in my last update.
msg386298 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2021-02-03 18:16
Distutils is now deprecated (see PEP 632) and all tagged issues are being closed. From now until removal, only release blocking issues will be considered for distutils.

If this issue does not relate to distutils, please remove the component and reopen it. If you believe it still requires a fix, most likely the issue should be re-reported at https://github.com/pypa/setuptools
History
Date User Action Args
2021-02-03 18:16:18steve.dowersetstatus: open -> closed

nosy: + steve.dower
messages: + msg386298

resolution: out of date
stage: resolved
2019-04-26 03:26:34sabakausersetmessages: + msg340879
title: python ibm_db setup.py post install script does not seem to work from Anaconda -> distutils.sysconfig.get_python_lib behaves incorrectly when pip cache is enabled
2019-04-26 03:22:32sabakausersetnosy: + eric.araujo, dstufft
components: + Distutils, - Build
2019-04-22 05:42:31sabakausersetmessages: + msg340640
2019-04-18 09:43:48sabakausersetmessages: + msg340478
2019-04-16 10:01:58sabakausersetmessages: + msg340327
2019-04-16 09:41:31xtreaksetnosy: + xtreak
messages: + msg340325
2019-04-16 09:22:51sabakausercreate