gpt4 book ai didi

python - 在 setuputils 包中获取入口点脚本文件位置?

转载 作者:太空狗 更新时间:2023-10-29 18:28:54 26 4
gpt4 key购买 nike

所以我在 setup.py [console_scripts] 部分中定义了一个入口点。该命令已正确安装并且运行良好,但我需要一种方法来以编程方式找出脚本的路径(例如,在 Windows 上,它类似于 C:/my/virtual/env/scripts/my_console_script.exe)。我需要这个,这样我就可以将该脚本路径作为参数传递给其他命令,而不管包安装在哪里。 Setuputils 提供了 pkg_resources,但这似乎并没有公开任何实际获取原始安装路径的方法,只有可加载的对象。

编辑:为了使用例简单明了,这里是设置。

我有一个插件驱动的应用程序,可以与各种本地服务进行通信。这些插件之一与 NMS 包的警报接口(interface)相关联。这个警报包可以向任意处理程序发出警报的唯一方法是调用脚本 - 执行路径(在本例中为 console_scripts 入口点)注册为完整路径 - 这就是我需要获取的路径。

最佳答案

那么,您可以将 --install-option="--install-scripts=/usr/local/bin" 形式的选项传递给 pip 并且只需自己设置路径。但我理解为什么您可能不想在跨平台项目中对其进行硬编码。

因此,我们只需要找出setuptools 实际 使用的目录。不幸的是,路径是在一大堆实际设置代码的中间确定的,而不是在我们可以调用的单独函数中确定的。

所以下一步是编写一个自定义安装命令来观察并保存路径。 (就此而言,您还可以设置 self.install_scripts 到您在此自定义安装程序类中选择的目录,从而将那部分配置保存在一个地方(包) 而不是在包中和命令行参数中设置...)

例子:

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,
},
)

可能的异议:

  • 有些人不喜欢任何形式的代码生成。在这种情况下,它更像是配置,尽管将它放在包中的 .py 中可以很容易地从任何地方的 Python 代码获取。

  • 从表面上看,它看起来有点像 hack。但是,setuptools 专门设计用于允许自定义命令类。这里没有真正访问任何私有(private)的东西,除了可能使用 distribution 对象传递的值,这只是为了避免 global

  • 只获取目录,不获取可执行文件名。不过,根据您的入口点配置,您应该知道这些名称。获取名称需要调用入口点规范的解析方法并生成更多代码。

  • 如果您需要修复一些错误,例如无需安装即可构建。不过 sdist 是安全的。

  • develop 是可能的,但需要另一个命令类。 install 不会被调用,build_py 只会在您设置 use_2to3 时被调用。自定义 develop 命令可以获得与 install 示例相同的路径,但作为 self.script_dir。从那里您必须决定是否愿意将文件写入您的源目录,该目录位于 self.egg_path 中——因为它稍后会被 install 获取,虽然它应该是同一个文件(并且构建命令无论如何都会覆盖该文件)

附录

这一点点洞察力可能更优雅,因为它不需要在任何地方保存路径,但仍会获得 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

附录 2

刚刚意识到/记得 pipegg-info 中创建了一个 installed-files.txt,这是一个相对路径列表到包括脚本在内的所有文件的包根目录。 pkg_resources.get_distribution('mypackage').get_metadata('installed-files.txt') 会得到这个。它只是一个 pip 东西,不是由 setup.py install 创建的。您需要逐行查找您的脚本名称,然后根据您的包目录获取绝对路径。

关于python - 在 setuputils 包中获取入口点脚本文件位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25066084/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com