如何使用python软件包分发字体? [英] How do I distribute fonts with my python package?
问题描述
我创建了一个名为 clearplot 的程序包,该程序包围绕matplotlib。我还创建了一个很好的字体,希望随包一起分发。我查阅了Python包装的本节用户指南,并确定我应该使用 data_files
关键字。我选择 data_files
而不是 package_data
,因为我需要将字体安装在 outside 。
I have created a package called clearplot that wraps around matplotlib. I have also created a nice font that I want to distribute with my package. I consulted this section of the Python Packaging User guide, and determined that I should use the data_files
keyword. I chose data_files
instead of package_data
since I need to install the font in a matplotlib directory that is outside of my package.
这是我的第一个有缺陷的尝试,尝试使用 setup.py
文件:
Here is my first, flawed, attempt at a setup.py
file:
from distutils.core import setup
import os, sys
import matplotlib as mpl
#Find where matplotlib stores its True Type fonts
mpl_data_dir = os.path.dirname(mpl.matplotlib_fname())
mpl_ttf_dir = os.path.join(mpl_data_dir, 'fonts', 'ttf')
setup(
...(edited for brevity)...
install_requires = ['matplotlib >= 1.4.0, !=1.4.3', 'numpy >= 1.6'],
data_files = [
(mpl_ttf_dir, ['./font_files/TeXGyreHeros-txfonts/TeXGyreHerosTXfonts-Regular.ttf']),
(mpl_ttf_dir, ['./font_files/TeXGyreHeros-txfonts/TeXGyreHerosTXfonts-Italic.ttf'])]
)
#Try to delete matplotlib's fontList cache
mpl_cache_dir = mpl.get_cachedir()
mpl_cache_dir_ls = os.listdir(mpl_cache_dir)
if 'fontList.cache' in mpl_cache_dir_ls:
fontList_path = os.path.join(mpl_cache_dir, 'fontList.cache')
os.remove(fontList_path)
<$>有两个问题c $ c> setup.py :
- 我尝试在
setup之前导入matplotlib ()
有机会安装它。这是一个显而易见的嘘声,但在运行setup()
之前,我需要知道mpl_ttf_dir
的位置。 - 如此处,则车轮分配不支持
data_files
的绝对路径。我认为这不会成为问题,因为我认为我只会使用sdist分布。 (sdists允许绝对路径。)然后,我发现pip 7.0(及更高版本)将所有包都转换为wheel发行版,即使该发行版最初是作为sdist创建的。
- I attempt to import matplotlib before
setup()
has a chance to install it. This is an obvious booboo, but I needed to know wherempl_ttf_dir
was before I ransetup()
. - As mentioned here, wheel distributions do not support absolute paths for
data_files
. I didn't think this would be a problem because I thought I would just use a sdist distribution. (sdists do allow absolute paths.) Then I came to find out that pip 7.0 (and later) converts all packages to wheel distributions, even if the distribution was originally created as a sdist.
问题2使我非常恼火,但是从那时起,我发现绝对路径很糟糕,因为它们不适用于virtualenv。因此,我现在愿意改变方法,但是我该怎么办?
I was quite annoyed by issue #2, but, since then, I found out that absolute paths are bad because they do not work with virtualenv. Thus, I am now willing to change my approach, but what do I do?
我唯一的想法是将字体分配为 package_data
首先,然后使用 os
模块将字体移动到正确的位置。
The only idea I have is to distribute the font as package_data
first and then move the font to the proper location afterwards using the os
module. Is that a kosher method?
推荐答案
感谢@benjaoming的回答和此博客文章,这是我想出的:
Thanks to @benjaoming's answer and this blog post, here is what I came up with:
from setuptools import setup
from setuptools.command.install import install
import warnings
#Set up the machinery to install custom fonts. Subclass the setup tools install
#class in order to run custom commands during installation.
class move_ttf(install):
def run(self):
"""
Performs the usual install process and then copies the True Type fonts
that come with clearplot into matplotlib's True Type font directory,
and deletes the matplotlib fontList.cache
"""
#Perform the usual install process
install.run(self)
#Try to install custom fonts
try:
import os, shutil
import matplotlib as mpl
import clearplot as cp
#Find where matplotlib stores its True Type fonts
mpl_data_dir = os.path.dirname(mpl.matplotlib_fname())
mpl_ttf_dir = os.path.join(mpl_data_dir, 'fonts', 'ttf')
#Copy the font files to matplotlib's True Type font directory
#(I originally tried to move the font files instead of copy them,
#but it did not seem to work, so I gave up.)
cp_ttf_dir = os.path.join(os.path.dirname(cp.__file__), 'true_type_fonts')
for file_name in os.listdir(cp_ttf_dir):
if file_name[-4:] == '.ttf':
old_path = os.path.join(cp_ttf_dir, file_name)
new_path = os.path.join(mpl_ttf_dir, file_name)
shutil.copyfile(old_path, new_path)
print "Copying " + old_path + " -> " + new_path
#Try to delete matplotlib's fontList cache
mpl_cache_dir = mpl.get_cachedir()
mpl_cache_dir_ls = os.listdir(mpl_cache_dir)
if 'fontList.cache' in mpl_cache_dir_ls:
fontList_path = os.path.join(mpl_cache_dir, 'fontList.cache')
os.remove(fontList_path)
print "Deleted the matplotlib fontList.cache"
except:
warnings.warn("WARNING: An issue occured while installing the custom fonts for clearplot.")
setup(...
#Specify the dependencies and versions
install_requires = ['matplotlib >= 1.4.0, !=1.4.3', 'numpy >= 1.6'],
#Specify any non-python files to be distributed with the package
package_data = {'' : ['color_maps/*.csv', 'true_type_fonts/*.ttf']},
#Specify the custom install class
cmdclass={'install' : move_ttf}
)
这解决了问题1(在导入之前先安装matplotlib)和问题2(可与轮子配合使用)。
This solves both problem #1 (it installs matplotlib before it imports it) and problem #2 (it works with wheels).
这篇关于如何使用python软件包分发字体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!