× К оглавлению На главную Об авторе

Дата и время публикации:    

Проблема и решение

1. Суть проблемы

Заключается в том, что все написанное на Python не относится к компилируемому или собираемому коду, т.к. выполняется в интерпретаторе бинарного кода CPython и находится в уже относительного виде исполняемых сценариев или подключаемых модулей другими сценариями по ходу выполнения.

Поэтому для СPython предусмотрена команда Python Package Index (PIP), с помощью которой мной будет собран и установлен пакет, который имеет shellenv-run.py и подключаемый им файл модуля shellenv.py проекта python-shellenv

2. Решение

2.1 Структура проекта python-shellenv

Пусть имеем два файла shellenv-run.py и подключаемый им модуль shellenv.py, а также README.md, как показано в дампе 2.1.1

Дамп 2.1.1

~/Projects/python-shellenv$ exa --tree .
.
├── README.md
└── shellenv
    ├── shellenv-run.py
    └── shellenv.py

Но, этого мало потому что структура пакета shellenv, должна содержать ряд файлов, которые используются утилитами подобно pip [3.3] и build [3.4] для построения пакета [3.1]

Поэтому, чтобы на выходе сборки получить пакет shellenv, показанную только что структуру нужно привести к удобоваримому виду, как показано в дампе 2.1.2

Дамп 2.1.2

~/Projects/python-shellenv$ exa --tree -L 3.
.
├── LICENSE
├── pyproject.toml
├── README.md
├── setup.cfg
└── src
   └── shellenv_module
     ├── __init__.py
     ├── shellenv-run.py
     └── shellenv.py

Поддиректория src/shellenv_module проекта python-shellenv должна содержать __init__.py, если считается, что она содержит файлы пакета. Таким образом, это позволяет избежать директории с общими именами, такими как string, которые могут встретится на пути позднее во время поиска составных частей модуля. При этом, в самом простом случае, __init__.py может быть пустым файлом, но так же может содержать исполняемый код для пакета или устанавливать переменную __all__, как показано в листинге 2.1.3

Листинг 2.1.3

all = [ 'shellenv' ]

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

Листинг 2.1.4

...
from shellenv_module import  shellenv
...

Теперь можно наполнить файлы pyproject.toml, setup.cfg и LICENSE

Файл pyproject.toml

Cодержит требования для построения текущего проекта с использованием инструмента setuptools, позволяющего с легкостью создавать дистрибутивы на базе и с учетом зависимостей пакетов окружения python [3.5]. Содержимое файла pyproject.toml приведен в листинге 2.1.5

Листинг 2.1.5

# This is a TOML document.

title = "TOML's file for the My Project"

[build-system]
requires = [
"setuptools>=42",
"wheel"
]
build-backend = "setuptools.build_meta"

Согласно, PEP 518 для построения пакетов в Python нужен файл проекта с расширением .toml должна содержать таблицу [build-system], которая разрешает зависимости [3.6]. При этом, build-system.requires предоставляет список пакетов, которые необходимы, чтобы построить пакет.

Файл setup.cfg

Теперь, после настройки учета зависимостей, нужно наполнить файл setup.cfg с таблицами метаданных, которые приведены в листинге 2.1.6

Листинг 2.1.6

[metadata]
name = shellenv_module-rjaan
version = 1.0
author = Andrew Rzhavskov
author_email = rjaan@yandex.ru
description = print SHELL's enviroment variables on standard output   
long_description = file: README.md
long_description_content_type = text/markdown
url = https://localhost/python-shellenv.git
project_urls =
    Bug Tracker = https://localhost/.../issues
classifiers =
    Programming Language :: Python :: 3
    License :: OSI Approved :: MIT License
    Operating System :: OS Independent

[options]
package_dir =
    = src
packages = find:
python_requires = >=3.8

[options.packages.find]
where = src

В котором предлагаю особо взглянуть на опции пакета в таблице [options] и [options.packages.find], где корневая директория поиска файлов пакета. Потому что в назначении остальных полей таблицы [metadata] мне не представляется сложным для чего они предназначаются.

Листинг 2.1.7

В таблице [options] указывается одна из распространенных конфигураций пакета, когда все модули (файлы) исходного кода находятся в поддиректории часто называемой src [3.7], в которой находится поддиректория shellenv_module, как показанно в дампе 2.1.7,

Дамп 2.1.7

~/Projects/python-shellenv$ exa --tree --ignore-glob="*~|__pycache__|dist|*.egg-info"
.
├── LICENSE
├── pyproject.toml
├── README.md
├── setup.cfg
├── shellenv.py
└── src
   └── shellenv_module
      ├── __init__.py
      ├── shellenv-run.py
      └── shellenv.py

Для устранения избыточности букв в имени пакета, особенно при локальном использовании, рекомендую сократить имя директории с src/shellenv_module на src/shellenv и изменить название пакета в опции name в таблице [metadata] с shellenv_module-rjaan на shellenv также.

На завершающем этапе формирования структуры пакета наполняем файл LICENSE c условиями распространения под лицензией MIT и файл README.md для публикации GitHub или в своем локальном хранилище Git репозитариев. Содержимое указанных файлов приведено в листинге 2.1.8 и 2.1.9 соответственно.

Листинг 2.1.8

Copyright (c) 2018 The Python Packaging Authority

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

 

Листинг 2.1.9

# (python-)shellenv is python's module to operate with environment variables   

  **shellenv(_module)** is python's module to display enviroment info and 
  it's consisting of two files written on Python. Both files may use as either 
  an executed script or included module.

  ...

  This project is licensed under the Python Software Foundation License Version 2.

2.2 Сборка и установка пакета

Перед началом сборки пакета рекомендую обновить pip до последней версии, как показано в дампе 2.2.1

Дамп 2.2.1


python3 -m pip install --upgrade pip

Затем, нам нужно установить модуль build, если он не был установлен ранее, как показано в дампе 2.2.2

Дамп 2.2.2

~/Projects/python-shellenv$ python3 -m pip install --upgrade build
Defaulting to user installation because normal site-packages is not writeable
Collecting build
  Downloading build-0.7.0-py3-none-any.whl (16 kB)
Collecting tomli>=1.0.0
  Downloading tomli-2.0.1-py3-none-any.whl (12 kB)
Collecting pep517>=0.9.1
  Downloading pep517-0.12.0-py2.py3-none-any.whl (19 kB)
Collecting packaging>=19.0
  Downloading packaging-21.3-py3-none-any.whl (40 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 40.8/40.8 KB 483.1 kB/s eta 0:00:00
Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /usr/lib/python3/dist-packages (from packaging>=19.0->build) (2.4.7)
Installing collected packages: tomli, packaging, pep517, build
  WARNING: The script pyproject-build is installed in '/home/user/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed build-0.7.0 packaging-21.3 pep517-0.12.0 tomli-2.0.1

Модуль build используется для генерации дистрибутива пакетов, который будет создан командой, указанной в дампе 2.2.3

Дамп 2.2.3

~/Projects/python-shellenv$ python3 -m build
ERROR Source /home/user/Projects/python-shellenv does not appear to be a Python project: no pyproject.toml or setup.py

Выполнение команды python3 -m build, которая закончилось с ошибкой: "no pyproject.toml or setup.py", потому что файлы проекта должны иметь статическую конфигурацию в pyproject.toml или динамическую в setup.py. Поэтому мне пришлось переименовать ранее названный по недразумению файл статической конфмгурации shellenv.toml в pyproject.toml и повторно запустить генерацию подгружаемого RIP архива, как показано в дампе 2.2.4

Дамп 2.2.4

~/Projects/python-shellenv$ python3 -m build
* Creating venv isolated environment...
* Installing packages in isolated environment... (setuptools>=42, wheel)
* Getting dependencies for sdist...
...
Successfully built shellenv-package-rjaan-0.1.tar.gz and shellenv_package_rjaan-0.1-py3-none-any.whl

Далее, полученные файлы закладываем в локальный индексный репозитарий пакетов Python, который находится в директории, например, как у меня в /home/git/pypisrv/, как показано в дампе 2.2.5а (неоптимизированное имя) или в дампе 2.2.5б (ноптимизированное имя)

Дамп 2.2.5a

~ /home/git/pypisrv$ exa --tree  
.
├── shellenv/
  └── shellenv-package-rjaan-0.1.tar.gz

Дамп 2.2.5б

~ /home/git/pypisrv$ exa --tree  
.
├── shellenv/
  └── shellenv-1.3.tar.gz

После чего, можно выполнить установку пакета shellenv, как показано в дампе 2.2.6 для версии пакета с оптимизированной версией

Дамп 2.2.6

pip install --upgrade -U shellenv --extra-index-url http://localhost:8080/simple

При этом, если использовать --index-url, то возникает ошибка разршения зависимостей, которую проще обойти с помощью опцией --extra-index-url. При этом, следует учитывать, что рекомендуемая опция --no-deps с --index-url [3.9] не всегда приносит, даже если устанавить все пакеты в локальный индексный репозитарий пакетов Python.

В дампе 2.2.7 приводится пример импорта shellenv и получение значения переменной окружения $HOME

Дамп 2.2.7

>>> import shellenv
>>> shellenv.getenv('HOME')
'/home/user'     

 

3. Библиография

3.1 Python Packaging User Guide -- packaging projects

3.2 The __init__.py,on the module search path.

3.3 Python Packaging User Guide -- pip

3.4 Python Packaging User Guide -- build

3.5 Python Packaging User Guide - setuptools

3.6 PEP 518 – Specifying Minimum Build System Requirements for Python Projects

3.7 Configuring setup() using setup.cfg files

3.8 what is the common header format of python-files

3.9 pip: force install ignoring dependencies

Сайт разработан в соответствии с рекомендациями консорциума W3C для языка разметки HTML5.

Об авторе можно прочитать здесь.

Copyright © 2015-2019 Андрей Ржавсков