2017-10-23 3 views
0

Ich möchte die Versionsnummer meines Pakets an einem einzigen Ort leben, wo alles, was es braucht, darauf verweisen kann.Zugriff auf Textdatei im Projektstamm aus Python-Paket unter `src /` Verzeichnis

Ich habe mehrere Vorschläge in diesem Python-Handbuch zu Single Sourcing the Package Version gefunden und beschlossen, # 4 zu versuchen, es in einer einfachen Textdatei in meinem Projekt-Stamm mit dem Namen VERSION zu speichern.

Hier ist eine verkürzte Version des Verzeichnisbaum meines Projektes (kann man das sehen the full project on GitHub):

. 
├── MANIFEST.in 
├── README.md 
├── setup.py 
├── VERSION 
├── src/ 
│   └── fluidspaces/ 
│    ├── __init__.py 
│    ├── __main__.py 
│    ├── i3_commands.py 
│    ├── rofi_commands.py 
│    ├── workspace.py 
│    └── workspaces.py 
└── tests/ 
   ├── test_workspace.py 
   └── test_workspaces.py 

Da VERSION und setup.py sind Geschwister, ist es sehr einfach, die Version Datei im Setup-Skript zu lesen und tun, was auch immer Ich will damit. Die VERSION und src/fluidspaces/__main__.py sind keine Geschwister und das Hauptmodul kennt den Pfad des Projektstamms nicht.

Der Führer hatte diese Erinnerung:

Achtung: Mit diesem Ansatz müssen Sie die Version-Datei wird in allen Quell- und Binärdistributionen enthalten stellen Sie sicher, dass (z hinzufügen umfassen VERSION zu Ihrem MANIFEST.in).

Das schien vernünftig - das Projekt Stammpfad benötigt anstelle von Paket-Module, die Versionsdatei in das Paket zum Zeitpunkt der Erstellung für die einfachen Zugriff kopiert werden konnte - aber ich fügte hinzu, dass Leitung zum Manifest und die Versionsdatei doesn noch Es scheint, als würde man nirgends im Build auftauchen.

Um zu bauen, starte ich pip install -U . aus dem Projekt root und in einem virtualenv. Hier sind die Ordner, die in <virtualenv>/lib/python3.6/site-packages als Ergebnis erstellt erhalten:

fluidspaces/ 
├── i3_commands.py 
├── __init__.py 
├── __main__.py 
├── __pycache__/ # contents snipped 
├── rofi_commands.py 
├── workspace.py 
└── workspaces.py 
fluidspaces-0.1.0-py3.6.egg-info/ 
├── dependency_links.txt 
├── entry_points.txt 
├── installed-files.txt 
├── PKG-INFO 
├── SOURCES.txt 
└── top_level.txt 

Mehr meiner Konfigurationsdateien:

MANIFEST.in:

include README.md 
include VERSION 
graft src 
prune tests 

setup.py:

#!/usr/bin/env python3 

from setuptools import setup, find_packages 


def readme(): 
    '''Get long description from readme file''' 
    with open('README.md') as f: 
     return f.read() 


def version(): 
    '''Get version from version file''' 
    with open('VERSION') as f: 
     return f.read().strip() 


setup(
    name='fluidspaces', 
    version=version(), 
    description='Navigate i3wm named containers', 
    long_description=readme(), 
    author='Peter Henry', 
    author_email='[email protected]', 
    url='https://github.com/mosbasik/fluidspaces', 
    license='MIT', 
    classifiers=[ 
     'Development Status :: 3 - Alpha', 
     'Programming Language :: Python :: 3.6', 
    ], 
    packages=find_packages('src'), 
    include_package_data=True, 
    package_dir={'': 'src'}, 
    package_data={'': ['VERSION']}, 
    setup_requires=[ 
     'pytest-runner', 
    ], 
    tests_require=[ 
     'pytest', 
    ], 
    entry_points={ 
     'console_scripts': [ 
      'fluidspaces = fluidspaces.__main__:main', 
     ], 
    }, 
    python_requires='~=3.6', 
) 

Ich fand diese SO Frage Any python function to get “data_files” root directory?, die mich denken lassen, dass die pkg_resources Bibliothek die Antwort auf meine Probleme ist, aber ich war nicht in der Lage, herauszufinden, wie man es in meiner Situation verwendet.

Ich habe Probleme gehabt, weil die meisten Beispiele, die ich gefunden habe, Python-Pakete direkt im Projektstamm haben anstatt isoliert in einem Verzeichnis src/.Ich bin mit einem src/ Verzeichnis wegen Empfehlungen wie diese:

Andere Knöpfe ich gefunden habe und versuchte, ein wenig verdreht sind die package_data, include_package_data und data_files kwargs für setup(). Ich weiß nicht, wie relevant sie sind. Scheint, als gäbe es ein Wechselspiel zwischen Dingen, die mit diesen deklariert sind, und Dingen, die im Manifest deklariert sind, aber ich bin mir nicht sicher über die Details.

Antwort

0

Habe mit einigen Leuten im #python IRC Channel auf Freenode über dieses Problem gechattet. Ich habe gelernt:

  • pkg_resources war wahrscheinlich wie sollte ich zu tun, was ich für bat, aber es würde erfordern die Versionsdatei in dem Paketverzeichnis anstelle des Projekts root setzen.
  • In setup.py konnte ich in einer solchen Versionsdatei aus dem Paketverzeichnis lesen, ohne das Paket selbst zu importieren (ein No-No aus ein paar Gründen), aber es würde hart codieren den Pfad vom Stamm zum Paket, das ich wollte vermeiden.

Schließlich entschied ich das setuptools_scm Paket verwenden Versionsinformationen von meinen git-Tags statt aus einer Datei in meinem Repo (jemand anderes tat, dass mit ihrem Paket und ihren Argumenten waren überzeugend) zu erhalten.

Als Ergebnis bekam ich meine Versionsnummer in setup.py sehr leicht:

setup.py:

from setuptools import setup, find_packages 

def readme(): 
    '''Get long description from readme file''' 
    with open('README.md') as f: 
     return f.read() 

setup(
    name='fluidspaces', 
    use_scm_version=True, # use this instead of version 
    description='Navigate i3wm named containers', 
    long_description=readme(), 
    author='Peter Henry', 
    author_email='[email protected]', 
    url='https://github.com/mosbasik/fluidspaces', 
    license='MIT', 
    classifiers=[ 
     'Development Status :: 3 - Alpha', 
     'Programming Language :: Python :: 3.6', 
    ], 
    packages=find_packages('src'), 
    package_dir={'': 'src'}, 
    setup_requires=[ 
     'pytest-runner', 
     'setuptools_scm', # require package for setup 
    ], 
    tests_require=[ 
     'pytest', 
    ], 
    entry_points={ 
     'console_scripts': [ 
      'fluidspaces = fluidspaces.__main__:main', 
     ], 
    }, 
    python_requires='~=3.6', 
) 

aber ich landete einen hartcodierten Pfad zu haben, der anzeigt, was die Projekt-Root sollte in Bezug auf die Paket-Code sein, die Art von was ich zuvor vermieden hatte. Ich denke, this issue on the setuptools_scm GitHub repo könnte sein, warum dies notwendig ist.

src/fluidspaces/__ main__.py:

import argparse 
from setuptools_scm import get_version # import this function 

def main(args=None): 
    # set up command line argument parsing 
    parser = argparse.ArgumentParser() 
    parser.add_argument('-V', '--version', 
         action='version', 
         version=get_version(root='../..', relative_to=__file__)) # and call it here 
Verwandte Themen