如何在buildout脚本中设置默认编码,或者在virtualenv创建期间设置默认编码?

时间:2015-02-13 16:33:17

标签: encoding plone buildout

我有一个由buildout脚本创建的Plone项目,需要默认编码utf-8。这通常在Python安装的sitecustomize.py文件中完成。由于存在virtualenv,我想自动生成此文件,以包含类似:

的内容
import sys
sys.setdefaultencoding('utf-8')

生成后,我有两个空sitecustomize.py个文件 - 一个在parts/instance/,一个在parts/buildout;但似乎没有使用这些(我在sys.path中找不到它们。)

我试过zopepy

>>> from os.path import join, isfile
>>> from pprint import pprint
>>> import sys
>>> pprint([p for p in sys.path
...         if isfile(join(p, 'sitecustomize.py'))
...         ])

在我的本地lib/python2.7/site-packages/目录中找到了另一个看起来不错的内容;但它不起作用:

>>> import sys
>>> sys.getdefaultencoding()
'ascii'

此目录位于sys.path的末尾附近,因为我需要通过extra-paths条目添加它(以获取另一个历史包)。

任何指针?谢谢!

系统信息:CentOS 7,Python 2.7.5

修改: 我删除了两个空sitecustomize.py个文件;现在我在utf-8会话中的默认编码为zopepy但在Plone中仍为ascii;这让我感到惊讶,因为我的构建脚本中有:

[zopepy]
recipe=zc.recipe.egg
eggs = ${instance:eggs}
extra-paths = ${instance:extra-paths}
interpreter = zopepy
scripts = zopepy

为了调试这个,我创建了一个我添加到代码中的小函数,它在sys.path中显示了一些关于相关模块的信息:

import sys
from os.path import join, isdir, isfile

def sitecustomize_info():
    plen = len(sys.path)
    print '-' * 79
    print 'sys.path has %(plen)d entries' % locals()
    for tup in zip(range(1, plen+1), sys.path):
        nr, dname = tup
        if isdir(dname):
            for fname in ('site.py', 'sitecustomize.py'):
                if isfile(join(dname, fname)):
                    print '%(nr)4d. %(dname)s/%(fname)s' % locals()
            spname = join(dname, 'site-packages', 'sitecustomize.py')
            if isfile(spname):
                print '%(nr)4d. %(spname)s' % locals()
        else:
            print  '?     %(dname)s is not a directory' % locals()
    print '-' * 79

输出:

sys.path has 303 entries
   8. /usr/lib64/python2.7/site-packages/sitecustomize.py
 295. /opt/zope/instances/wnzkb/lib/python2.7/site-packages/sitecustomize.py
?     /usr/lib64/python27.zip is not a directory
 298. /usr/lib64/python2.7/site.py
?     /usr/lib64/python2.7/lib-tk is not a directory
?     /usr/lib64/python2.7/lib-old is not a directory
 303. /usr/lib/python2.7/site-packages/sitecustomize.py

所有sitecustomize.py个文件看起来都一样(切换到utf-8),我没有调整site.py(现在;如果其他一切都失败了,我可能需要。)< / p>

2 个答案:

答案 0 :(得分:1)

如果您真的希望/需要使用sitecustomize.py技巧,您可以将此部分包含在您的buildout中:

[fixencode]
recipe = plone.recipe.command
stop-on-error = yes
update-command = ${fixencode:command}
command =
    SITE_PACKAGES=$(${buildout:executable} -c \
      'from distutils.sysconfig import get_python_lib;print(get_python_lib())')
    cat >  $SITE_PACKAGES/../sitecustomize.py << EOF
    #!${buildout:executable} -S
    import sys
    sys.setdefaultencoding('utf-8')
    EOF

它将被添加到virtualenv的site-packages文件夹中。

答案 1 :(得分:0)

除非放在全局sitecustomize.py目录(Discussion "deleting setdefaultencoding in site.py is evil" (2009)Tracker ticket "sitecustomize.py not found")中,否则找不到lib - 这是故意制作的(!)。

这是为了防止用户覆盖某些库已调整可能的默认编码。但是,图书馆不应该这样做。

因此,任何需要设置默认编码的人都会被诱惑全局地执行它,这对我来说看起来是一个非常愚蠢的想法。我认为在我的虚拟环境讽刺中设置它会更合理。

不幸的是,virtualenv中的sitecustomize.py模块似乎被默默地忽略了;但是可以编辑本地site.py。这是一个小sed脚本:

#                     vv-------1------vv vv---2---vv vv--------3------vv vv-----------4------------vv
sed --in-place -e 's,^\(    encoding =\) \("ascii"\) \(# Default value\) \(set by _PyUnicode_Init()\),\1 "utf-8" \3 \2 \4,' lib/python2.7/site.py