Tyl*_*ves 10 python setuptools
所以我在setup.py [console_scripts]部分中定义了一个入口点.该命令已正确安装并正常工作,但我需要一种方法以编程方式找到脚本的路径(例如,在Windows上它将类似于C:/my/virtual/env/scripts/my_console_script.exe).我需要这个,所以我可以将该脚本路径作为参数传递给其他命令,无论软件包安装在何处.Setuputils提供了pkg_resources,但似乎没有暴露实际获取原始安装路径的任何方式,只有可加载对象.
编辑:要使用例是明确的设置.
我有一个插件驱动的应用程序,可以与各种本地服务进行通信.其中一个插件与NMS包的警报界面相关联.此警报包可以向任意处理程序发出警报的唯一方法是调用脚本 - 执行的路径(在本例中为console_scripts入口点)注册为完整路径 - 这是我需要获取的路径.
嗯,你可以通过以下形式的选项--install-option="--install-scripts=/usr/local/bin"来pip,只是为自己设定的路径.但我明白为什么你可能不想在跨平台项目中硬编码.
所以,我们只需要找出目录setuptools的实际使用.不幸的是,路径是在一大堆实际设置代码的中间确定的,而不是在我们可以调用的单独函数中.
因此,下一步是编写一个观察并保存路径的自定义安装命令.(就此而言,你也可以在这个自定义安装程序类中设置 self.install_scripts一个你选择的目录,从而将该部分配置保存在一个地方(包)而不是在包中和命令行arg中设置... )
例:
from setuptools import setup
from setuptools.command.install import install
from distutils.command.build_py import build_py
import os
class InstallReadsScriptDir(install):
def run(self):
self.distribution._x_script_dir = self.install_scripts
install.run(self)
class BuildConfiguresScriptDir(build_py):
def run(self):
build_py.run(self)
if self.dry_run:
return
script_dir = self.distribution._x_script_dir # todo: check exists
target = os.path.join(self.build_lib, 'mypackage', 'scriptdir.py')
with open(target, 'w') as outfile:
outfile.write('path = """{}"""'.format(script_dir))
setup(
name="MyPackage",
version='0.0.1',
packages = ['mypackage'],
entry_points = {
'console_scripts': [
'footest = mypackage:main',
],
},
cmdclass= {
'install': InstallReadsScriptDir,
'build_py': BuildConfiguresScriptDir,
},
)
Run Code Online (Sandbox Code Playgroud)
可能的反对意见:
有些人不喜欢任何形式的代码生成.在这种情况下,它更像是配置,虽然将它放在.py包中可以很容易地从Python代码中获取.
从表面上看,它看起来有点像黑客.但是,setuptools专门设计为允许自定义命令类.这里没有任何东西真正访问任何私有,除了可能使用distribution对象传递的值,这只是为了避免global.
只获取目录,而不是可执行文件名.您应该根据入口点配置知道名称.获取名称需要调用入口点规范的解析方法并生成更多代码.
如果您在没有安装的情况下进行构建,则需要一些错误修正.sdist虽然很安全.
develop是可能的,但需要另一个命令类.install没有被调用,build_py只有在你设置时才被调用use_2to3.自定义develop命令可以获取install示例中的路径,但是self.script_dir.从那里你必须决定你是否愿意将文件写入你的源目录,self.egg_path因为它将在install以后被提取,尽管它应该是相同的文件(并且build命令将覆盖文件无论如何)
附录
这个小小的洞察力可能更优雅,因为它不需要在任何地方保存路径,但仍然获得实际路径setuptools使用,但它假设自安装以来没有配置发生变化.
from setuptools import Distribution
from setuptools.command.install import install
class OnlyGetScriptPath(install):
def run(self):
# does not call install.run() by design
self.distribution.install_scripts = self.install_scripts
def get_setuptools_script_dir():
dist = Distribution({'cmdclass': {'install': OnlyGetScriptPath}})
dist.dry_run = True # not sure if necessary, but to be safe
dist.parse_config_files()
command = dist.get_command_obj('install')
command.ensure_finalized()
command.run()
return dist.install_scripts
Run Code Online (Sandbox Code Playgroud)
附录2
刚刚意识到/记住,pip创建一个installed-files.txt在egg-info,这是相对于所有文件,包括脚本的包根的路径列表.pkg_resources.get_distribution('mypackage').get_metadata('installed-files.txt')会得到这个.这只是一pip件事,而不是由创造setup.py install.您需要遍历查找脚本名称的行,然后根据程序包的目录获取绝对路径.
| 归档时间: |
|
| 查看次数: |
3549 次 |
| 最近记录: |