Получение версии дистрибутива пакета Python из пакета - PullRequest
4 голосов
/ 08 мая 2019

Вы можете получить версию дистрибутива Python, используя

import pkg_resources
pkg_resources.get_distribution("distro").version

Это замечательно, если вы знаете имя дистрибутива, однако мне нужно динамически определить имя моего дистрибутива во время выполнения.

# Common framework base app class, extended by each app
class App(object):
    def get_app_version(self) -> str:
        package_name = self.__class__.__module__.split('.')[0]
        try:
            return pkg_resources.get_distribution(package_name).version
        except Exception:
            return "development"

Это работает для случаев, когда имя пакета приложения совпадает с именем дистрибутива (например, requests). Однако это не удается, если они не совпадают (например, my-app содержит пакет my_app).

Так что мне нужно сопоставление между дистрибутивами и их пакетами, которое, я уверен, должно где-то существовать, так как pip, кажется, знает, что удалять, когда вы вызываете uninstall:

$ pip uninstall requests
Uninstalling requests-2.21.0:
  Would remove:
    /home/user/.virtualenvs/app/lib/python3.6/site-packages/requests-2.21.0.dist-info/*
    /home/user/.virtualenvs/app/lib/python3.6/site-packages/requests/*

Как получить программный доступ к этому сопоставлению?

1 Ответ

0 голосов
/ 08 мая 2019

После нескольких часов изучения pkg_resources и чтения источника для удаления pip у меня работает следующее:

import inspect
import pkg_resources
import csv

class App(object):
    def get_app_version(self) -> str:
        # Iterate through all installed packages and try to find one that has the app's file in it
        app_def_path = inspect.getfile(self.__class__)
        for dist in pkg_resources.working_set:
            try:
                filenames = [
                    os.path.normpath(os.path.join(dist.location, r[0]))
                    for r in csv.reader(dist.get_metadata_lines("RECORD"))
                ]
                if app_def_path in filenames:
                    return dist.version
            except FileNotFoundError:
                # Not pip installed or something
                pass
        return "development"

Это перебирает все установленные пакеты, и для каждого из них перебирает свой список файлов и пытается сопоставить его с текущим файлом, это сопоставляет пакет с дистрибутивом. Это не совсем идеально, и я все еще открыт для лучших ответов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...