Life is short, you need Python – Bruce Eckel

日常开发中难免会与 Python 打交道,本文记录一些平时遇到的问题及解决方案:

升级pip所有安装包

这个也算是stackoverflow上一个经典问题了,下面就贴一下具体代码:

1
pip freeze --local | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install -U

另外,Github 上  有个issue专门做了需不需要为pip添加upgradeupgrade-all的讨论,有兴趣的可以去参与一下。


升级pyxattr遇到无法找到attr/xattr.h的问题

具体报错信息如下:

1
2
3
4
5
6
7
8
# centos7 / Python 2.7.5 / pip 9.0.1

gcc -pthread -fno-strict-aliasing -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -D_XATTR_VERSION="0.6.0" -D_XATTR_AUTHOR="Iustin Pop" -D_XATTR_EMAIL="iustin@k1024.org" -I/usr/include/python2.7 -c xattr.c -o build/temp.linux-x86_64-2.7/xattr.o -Wall -Werror -Wsign-compare
    xattr.c:29:24: fatal error: attr/xattr.h: No such file or directory
     #include <attr/xattr.h>
                            ^
    compilation terminated.
    error: command 'gcc' failed with exit status 1

如果你也碰到了上面的问题,解决方案很简单,安装一下对应的系统包就行了:

1
2
3
4
5
# Install RPM:
sudo yum install -y libattr-devel

# Install Deb:
sudo apt-get install -y libattr1-dev

升级pygpgme遇到无法找到gpgme.h的问题

具体报错信息如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# centos6 / Python 2.6.6 / pip 9.0.1

Running setup.py install for pygpgme ... error
    Complete output from command /usr/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-iYzzHD/pygpgme/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-6Ep2BO-record/install-record.txt --single-version-externally-managed --compile:
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-2.6
    creating build/lib.linux-x86_64-2.6/gpgme
    copying gpgme/editutil.py -> build/lib.linux-x86_64-2.6/gpgme
    copying gpgme/__init__.py -> build/lib.linux-x86_64-2.6/gpgme
    running build_ext
    building 'gpgme._gpgme' extension
    creating build/temp.linux-x86_64-2.6
    creating build/temp.linux-x86_64-2.6/src
    gcc -pthread -fno-strict-aliasing -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/usr/include/python2.6 -c src/gpgme.c -o build/temp.linux-x86_64-2.6/src/gpgme.o
    In file included from src/gpgme.c:22:
    src/pygpgme.h:24:19: error: gpgme.h: No such file or directory
    In file included from src/gpgme.c:22:
    src/pygpgme.h:32: error: expected specifier-qualifier-list before ‘gpgme_ctx_t’
    src/pygpgme.h:37: error: expected specifier-qualifier-list before ‘gpgme_key_t’
    src/pygpgme.h:42: error: expected specifier-qualifier-list before ‘gpgme_subkey_t’
    src/pygpgme.h:48: error: expected specifier-qualifier-list before ‘gpgme_user_id_t’
    src/pygpgme.h:54: error: expected specifier-qualifier-list before ‘gpgme_key_sig_t’
    src/pygpgme.h:124: error: expected ‘)’ before ‘err’
    src/pygpgme.h:125: error: expected ‘)’ before ‘err’
    src/pygpgme.h:126: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘pygpgme_check_pyerror’
    src/pygpgme.h:130: error: expected ‘)’ before ‘*’ token
    src/pygpgme.h:131: error: expected ‘)’ before ‘key’
    src/pygpgme.h:132: error: expected ‘)’ before ‘siglist’
    src/pygpgme.h:133: error: expected ‘)’ before ‘siglist’
    src/pygpgme.h:134: error: expected ‘)’ before ‘ctx’
    src/pygpgme.h:135: error: expected ‘)’ before ‘ctx’
    src/gpgme.c: In function ‘create_module’:
    src/gpgme.c:92: warning: implicit declaration of function ‘gpgme_check_version’
    src/gpgme.c:92: warning: assignment makes pointer from integer without a cast
    error: command 'gcc' failed with exit status 1

简单推测这个应该和系统的gpgme有关,Google 了一下,发现有人已经提出过这个问题Can’t upgrade to 0.3 on Centos 6.4,同时,William Grant 也给出了分析,需要 centos 系统安装gpgme-devel即可。

1
2
# Install RPM:
sudo yum install -y gpgme-devel

升级pycurl遇到无法找到gpgme.h的问题

具体报错信息如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# centos6 / Python 2.6.6 / pip 9.0.1

Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-vOVaGA/pycurl/setup.py", line 823, in <module>
        ext = get_extension(sys.argv, split_extension_source=split_extension_source)
      File "/tmp/pip-build-vOVaGA/pycurl/setup.py", line 497, in get_extension
        ext_config = ExtensionConfiguration(argv)
      File "/tmp/pip-build-vOVaGA/pycurl/setup.py", line 71, in __init__
        self.configure()
      File "/tmp/pip-build-vOVaGA/pycurl/setup.py", line 107, in configure_unix
        raise ConfigurationError(msg)
    __main__.ConfigurationError: Could not run curl-config: [Errno 2] No such file or directory

curl-config无法找到,十有八九跟系统的curl有关,查了一下,确实又是缺少了libcurl-devel,可以看一下这个gist

1
2
# Install RPM:
sudo yum install -y libcurl-devel

升级pipv9.*版本以后,遇到权限问题

1
OSError: [Errno 13] Permission denied: '/usr/lib/python2.7/dist-packages/attr/_compat.py'

解决方案有 2 种,第一种比较直接,用sudo权限,第二种就是启用pip--user配置项,例如,本文前面所说的升级全部的 pip package 时,命令修改如下:

1
pip freeze --local | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install --user

yum无法正常使用,提示pycurl有问题

1
2
3
4
5
6
7
There was a problem importing one of the Python modules
required to run yum. The error leading to this problem was:

   pycurl: libcurl link-time ssl backend (nss) is different from compile-time ssl backend (openssl)

Please install a package which provides this module, or
verify that the module is installed correctly.

看提示,应该是pycurl所依赖的libcurl用的是nss的 SSL 方案,但是pycurl使用的却是openssl的 SSL 方案,所以导致了冲突,果然,在stackoverflow上看到了相关的东西,解决方案也比较简单,如下操作即可:

1
2
3
pip uninstall pycurl
export PYCURL_SSL_LIBRARY=nss
pip install pycurl --no-cache-dir

排查了一下原因,发现可能是之前想玩 shadowsocks 的时候,安装了python-devel一系列之后又做了一次全局的依赖升级,导致了这个问题,有空了再去深究