Come posso ottenere la versione definita in setup.py (setuptools) nel mio pacchetto?


Risposte:


246

Interroga la stringa di versione della distribuzione già installata

Per recuperare la versione dall'interno del pacchetto in fase di runtime (ciò che la domanda sembra effettivamente porre), è possibile utilizzare:

import pkg_resources  # part of setuptools
version = pkg_resources.require("MyProject")[0].version

Memorizza la stringa di versione da utilizzare durante l'installazione

Se vuoi fare il contrario (che sembra essere quello che altri autori della risposta sembrano aver pensato che stavi chiedendo), metti la stringa della versione in un file separato e leggi il contenuto di quel file setup.py.

È possibile creare un version.py nel pacchetto con una __version__riga, quindi leggerlo da setup.py utilizzando execfile('mypackage/version.py'), in modo che sia impostato __version__nello spazio dei nomi setup.py.

Se vuoi un modo molto più semplice che funzioni con tutte le versioni di Python e anche con i linguaggi non Python che potrebbero aver bisogno di accedere alla stringa di versione:

Memorizza la stringa di versione come unico contenuto di un file di testo semplice, chiamato ad esempio VERSION, e leggi quel file durante setup.py.

version_file = open(os.path.join(mypackage_root_dir, 'VERSION'))
version = version_file.read().strip()

Lo stesso VERSIONfile funzionerà quindi esattamente anche in qualsiasi altro programma, anche in quelli non Python, e dovrai solo cambiare la stringa di versione in un posto per tutti i programmi.

Avviso sulle condizioni di gara durante l'installazione

A proposito, NON importare il pacchetto dal tuo setup.py come suggerito in un'altra risposta qui: sembrerà funzionare per te (perché hai già installato le dipendenze del pacchetto), ma causerà il caos sui nuovi utenti del pacchetto , poiché non saranno in grado di installare il pacchetto senza prima installare manualmente le dipendenze.


1
Questa è semplicemente la risposta migliore qui: il modo migliore è usare execfile se hai bisogno di setup.py per ottenere la versione dal tuo pacchetto.
trono,

2
execfilefunziona davvero bene ... ma (purtroppo) non funziona con Python 3.
medmunds

9
... OK, per Python 2 e 3 usare with open('mypackage/version.py') as f: exec(f.read())al posto di execfile('mypackage/version.py'). (Da stackoverflow.com/a/437857/647002 )
medmunds

5
La parte del caos non è necessariamente vera ... causerà il caos solo se il file init .py nel pacchetto ha dipendenze per l'importazione del codice (direttamente o indirettamente).
Pykler,

2
Vale la pena ricordare che django esegue una chiamata __import__ nel loro setup.py . '__Import__' vs 'import' lo rende sicuro? Non sembra causare loro alcun problema.
user1978019

33

studio di esempio: mymodule

Immagina questa configurazione:

setup.py
mymodule/
        / __init__.py
        / version.py
        / myclasses.py

Quindi immagina uno scenario abituale in cui hai dipendenze e setup.pyassomiglia a:

setup(...
    install_requires=['dep1','dep2', ...]
    ...)

E un esempio __init__.py:

from mymodule.myclasses import *
from mymodule.version import __version__

E per esempio myclasses.py:

# these are not installed on your system.
# importing mymodule.myclasses would give ImportError
import dep1
import dep2

problema n. 1: importazione mymoduledurante l'installazione

Se i vostri setup.pyimportazioni mymoduleallora durante l'installazione si sarebbe molto probabilmente ottenere una ImportError. Questo è un errore molto comune quando il pacchetto ha dipendenze. Se il tuo pacchetto non ha dipendenze diverse dai builtin, potresti essere al sicuro; tuttavia questa non è una buona pratica. La ragione di ciò è che non è a prova di futuro; dì domani che il tuo codice deve consumare qualche altra dipendenza.

problema n. 2: dov'è il mio __version__?

Se hardcode __version__in setup.pyallora non può corrispondere alla versione che si sarebbe spedito in modulo. Per essere coerenti, lo metti in un posto e lo leggi dallo stesso posto quando ne hai bisogno. L'utilizzo importpotrebbe causare il problema n. 1.

soluzione: à la setuptools

Dovresti usare una combinazione di open, exece fornire un comando per execaggiungere variabili:

# setup.py
from setuptools import setup, find_packages
from distutils.util import convert_path

main_ns = {}
ver_path = convert_path('mymodule/version.py')
with open(ver_path) as ver_file:
    exec(ver_file.read(), main_ns)

setup(...,
    version=main_ns['__version__'],
    ...)

E in mymodule/version.pyesporre la versione:

__version__ = 'some.semantic.version'

In questo modo, la versione viene fornita con il modulo e non si verificano problemi durante l'installazione durante il tentativo di importare un modulo con dipendenze mancanti (ancora da installare).


2
Questa sembra la soluzione più ragionevole perché si basa solo su dipendenze consentite.
Dogweather,

Il concetto di versione del pacchetto definito nel file setup.py è diverso dalla versione ?
variabile

16

La tecnica migliore consiste nel definire __version__il codice del prodotto, quindi importarlo in setup.py da lì. Questo ti dà un valore che puoi leggere nel tuo modulo in esecuzione e avere un solo posto per definirlo.

I valori in setup.py non sono installati e setup.py non si attacca dopo l'installazione.

Cosa ho fatto (ad esempio) in coverage.py:

# coverage/__init__.py
__version__ = "3.2"


# setup.py
from coverage import __version__

setup(
    name = 'coverage',
    version = __version__,
    ...
    )

AGGIORNAMENTO (2017): coverage.py non si importa più per ottenere la versione. L'importazione del proprio codice può renderlo non installabile, poiché il codice del prodotto proverà a importare dipendenze, che non sono ancora state installate, poiché setup.py è ciò che le installa.


4
@Evan: Non sono sicuro di quello che stai ottenendo riguardo a "solo estrarre quel valore dalla fonte". Se il file con __version__in esso è rotto in qualche modo, anche l'importazione verrà interrotta. Python non sa come interpretare solo le affermazioni che desideri. @pjeby ha ragione: se il tuo modulo deve importare altri moduli, potrebbero non essere ancora installati e sarà caotico. Questa tecnica funziona se stai attento che l'importazione non induca una lunga catena di altre importazioni.
Ned Batchelder,

1
@Ned Batchelder Sono abbastanza sicuro che, se metti la versione prima di qualsiasi importazione nel file di origine e solo in una "versione di importazione del modulo", non eseguirà il lex del file di origine più del necessario. Inoltre, chi rilascerà il codice non funzionante? Se il pacchetto necessita di dipendenze, usa setuptools o attendi il rilascio di distutils2 più avanti nell'anno.
Evan Plaice,

15
@Evan, mi dispiace, ma ti sbagli sull'importazione di file parziali. Prova a inserire un'istruzione print alla fine di un modulo lungo e importa la prima variabile definita nel file. Verrà eseguita la dichiarazione di stampa.
Ned Batchelder,

23
Mi sono innamorato di questo, ma @pjeby ha perfettamente ragione: "A proposito, NON importare il pacchetto dal tuo setup.py come suggerito in un'altra risposta qui: sembrerà funzionare per te (perché hai già installato le dipendenze del pacchetto ), ma causerà il caos sui nuovi utenti del pacchetto, in quanto non saranno in grado di installare il pacchetto senza prima installare manualmente le dipendenze. " Ned, ti dispiacerebbe aggiungere un avviso alla tua risposta?
Dr. Jan-Philip Gehrcke,

1
Come @ Jan-PhilipGehrcke quando aggiungo un file setup.py come questo per PyPI e poi pip install <packagename>, ricevo il seguente errore: ImportError: No module named <packagename>. AVVISO ai lettori che non è possibile eseguire file setup.py come questo in ambienti in cui il pacchetto non è già installato!
Piani cottura

14

La tua domanda è un po 'vaga, ma penso che quello che stai chiedendo sia come specificarlo.

È necessario definire in questo __version__modo:

__version__ = '1.4.4'

E quindi puoi confermare che setup.py conosce la versione che hai appena specificato:

% ./setup.py --version
1.4.4

9

Non ero contento di queste risposte ... non volevo richiedere setuptools, né creare un modulo completamente separato per una singola variabile, quindi ho pensato a queste.

Per quando sei sicuro che il modulo principale sia in stile pep8 e rimarrà tale:

version = '0.30.unknown'
with file('mypkg/mymod.py') as f:
    for line in f:
        if line.startswith('__version__'):
            _, _, version = line.replace("'", '').split()
            break

Se desideri essere molto attento e utilizzare un vero parser:

import ast
version = '0.30.unknown2'
with file('mypkg/mymod.py') as f:
    for line in f:
        if line.startswith('__version__'):
            version = ast.parse(line).body[0].value.s
            break

setup.py è in qualche modo un modulo usa e getta, quindi non è un problema se è un po 'brutto.


Aggiornamento: abbastanza divertente, mi sono allontanato da questo negli ultimi anni e ho iniziato a usare un file separato nel pacchetto chiamato meta.py. Ho inserito molti metadati che potrei voler cambiare frequentemente. Quindi, non solo per un valore.


+1. È relativamente semplice, mantiene il numero di versione in un posto, non richiede un file separato per contenerlo e non impone le dipendenze di importazione del modulo Python su setup.py. Non mi preoccuperei nemmeno del gestore del contesto in un programma di breve durata come setup.py.
ʇsәɹoɈ

Molto più bello dell'uso di regex, grazie. Puoi anche usarlo ast.get_docstring()con alcuni .split('\n')[0].strip()etc per compilare automaticamente descriptiondalla fonte. Una cosa in meno da mantenere sincronizzata
perso l'

4

Crea un file nella tua struttura di origine, ad esempio in yourbasedir / yourpackage / _version.py. Lascia che quel file contenga solo una singola riga di codice, in questo modo:

__version__ = "1.1.0-r4704"

Quindi in setup.py, apri quel file e analizza il numero di versione in questo modo:

verstr = "sconosciuto"
provare:
    verstrline = open ('yourpackage / _version.py', "rt"). read ()
tranne EnvironmentError:
    pass # Va bene, non esiste un file di versione.
altro:
    VSRE = r "^ __ version__ = ['\"] ([^' \ "] *) ['\"] "
    mo = re.search (VSRE, verstrline, re.M)
    se mo:
        verstr = mo.group (1)
    altro:
        raise RuntimeError ("impossibile trovare la versione nel tuo pacchetto / _version.py")

Infine, in yourbasedir/yourpackage/__init__.pyimport _version in questo modo:

__version__ = "sconosciuto"
provare:
    da _version import __version__
tranne ImportError:
    # Stiamo correndo su un albero che non ha _version.py, quindi non sappiamo quale sia la nostra versione.
    passaggio

Un esempio di codice che fa questo è il pacchetto "pyutil" che mantengo. (Vedi PyPI o ricerca su Google - StackOverflow non mi consente di includere un collegamento ipertestuale ad esso in questa risposta.)

@pjeby ha ragione a non importare il pacchetto dal proprio setup.py. Funzionerà quando lo testerai creando un nuovo interprete Python ed eseguendo setup.py in primo luogo:, python setup.pyma ci sono casi in cui non funzionerà. Questo perché import youpackagenon significa leggere l'attuale directory di lavoro per una directory denominata "yourpackage", significa cercare nella corrente sys.modulesuna chiave "yourpackage" e quindi fare varie cose se non è lì. Quindi funziona sempre quando lo fai python setup.pyperché hai un nuovo, vuoto sys.modules, ma questo non funziona in generale.

Ad esempio, cosa succede se py2exe sta eseguendo setup.py come parte del processo di creazione del pacchetto di un'applicazione? Ho visto un caso come questo in cui py2exe inseriva il numero di versione errato in un pacchetto perché il pacchetto stava ottenendo il suo numero di versione daimport myownthingin setup.py, ma una versione diversa di quel pacchetto era stata precedentemente importata durante l'esecuzione di py2exe. Allo stesso modo, cosa succede se setuptools, easy_install, distribut o distutils2 sta cercando di compilare il pacchetto come parte di un processo di installazione di un pacchetto diverso che dipende dal tuo? Quindi se il tuo pacchetto è impossibile al momento della valutazione di setup.py, o se esiste già una versione del pacchetto che è stata importata durante la vita di questo interprete Python o se importare il pacchetto richiede prima l'installazione di altri pacchetti o ha effetti collaterali, può modificare i risultati. Ho avuto diverse difficoltà nel provare a riutilizzare i pacchetti Python che hanno causato problemi a strumenti come py2exe e setuptools perché il loro setup.py importa il pacchetto stesso per trovare il suo numero di versione.

A proposito, questa tecnica si adatta perfettamente agli strumenti per creare automaticamente il yourpackage/_version.pyfile, ad esempio leggendo la cronologia dei controlli di revisione e scrivendo un numero di versione basato sul tag più recente nella cronologia dei controlli di revisione. Ecco uno strumento che lo fa per darcs: http://tahoe-lafs.org/trac/darcsver/browser/trunk/README.rst ed ecco uno snippet di codice che fa la stessa cosa per git: http: // github .com / Warner / python-ecdsa / blob / 0ed702a9d4057ecf33eea969b8cf280eaccd89a1 / setup.py # L34


3

Questo dovrebbe anche funzionare, usando espressioni regolari e in base ai campi dei metadati per avere un formato come questo:

__fieldname__ = 'value'

Utilizzare quanto segue all'inizio di setup.py:

import re
main_py = open('yourmodule.py').read()
metadata = dict(re.findall("__([a-z]+)__ = '([^']+)'", main_py))

Successivamente, puoi utilizzare i metadati nel tuo script in questo modo:

print 'Author is:', metadata['author']
print 'Version is:', metadata['version']

Come ho detto sopra, basta usare str.split :)
Éric Araujo,

Oh dio no. Stai analizzando Python in Python? Per lo meno, usa eval (), bambino.
slacy

3
Povero consiglio slacy, eval dovrebbe essere evitato quando è così facile.
Gringo Suave,

3

Con una struttura come questa:

setup.py
mymodule/
        / __init__.py
        / version.py
        / myclasses.py

dove version.py contiene:

__version__ = 'version_string'

Puoi farlo in setup.py :

import sys

sys.path[0:0] = ['mymodule']

from version import __version__

Ciò non causerà alcun problema con le dipendenze che hai nel tuo mymodule / __ init__.py


2

Per evitare di importare un file (e quindi eseguire il suo codice) è possibile analizzarlo e recuperare l' versionattributo dall'albero della sintassi:

# assuming 'path' holds the path to the file

import ast

with open(path, 'rU') as file:
    t = compile(file.read(), path, 'exec', ast.PyCF_ONLY_AST)
    for node in (n for n in t.body if isinstance(n, ast.Assign)):
        if len(node.targets) == 1:
            name = node.targets[0]
            if isinstance(name, ast.Name) and \
                    name.id in ('__version__', '__version_info__', 'VERSION'):
                v = node.value
                if isinstance(v, ast.Str):
                    version = v.s
                    break
                if isinstance(v, ast.Tuple):
                    r = []
                    for e in v.elts:
                        if isinstance(e, ast.Str):
                            r.append(e.s)
                        elif isinstance(e, ast.Num):
                            r.append(str(e.n))
                    version = '.'.join(r)
                    break

Questo codice tenta di trovare l' assegnazione __version__o VERSIONal livello superiore del ritorno del modulo è il valore di stringa. Il lato destro può essere una stringa o una tupla.


3
Sembra intelligente e complicato :) Sarebbe più semplice avere un file _version.py contenente un compito e analizzarlo con open-read-str.split.
Éric Araujo,

Grazie per aver pubblicato questo Penso che sia troppo complesso per questa situazione, ma molto utile per capire come si potrebbe affrontare il problema. Mi piace che mantiene il numero di versione in un posto, non richiede un file separato per contenerlo e non impone le dipendenze di importazione del modulo Python dallo script di installazione.
ɈsәɹoɈ

2

Esistono mille modi per scuoiare un gatto - ecco il mio:

# Copied from (and hacked):
# https://github.com/pypa/virtualenv/blob/develop/setup.py#L42
def get_version(filename):
    import os
    import re

    here = os.path.dirname(os.path.abspath(__file__))
    f = open(os.path.join(here, filename))
    version_file = f.read()
    f.close()
    version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
                              version_file, re.M)
    if version_match:
        return version_match.group(1)
    raise RuntimeError("Unable to find version string.")

2

Pulizia https://stackoverflow.com/a/12413800 da @ gringo-suave:

from itertools import ifilter
from os import path
from ast import parse

with open(path.join('package_name', '__init__.py')) as f:
    __version__ = parse(next(ifilter(lambda line: line.startswith('__version__'),
                                     f))).body[0].value.s

2

Ora questo è disgustoso e necessita di un po 'di raffinamento (potrebbe esserci persino una chiamata di un membro scoperto in pkg_resources che ho perso), ma semplicemente non vedo perché non funziona, né perché nessuno lo abbia suggerito fino ad oggi non acceso) ... nota che si tratta di Python 2.xe richiederebbe pkg_resources (sigh):

import pkg_resources

version_string = None
try:
    if pkg_resources.working_set is not None:
        disto_obj = pkg_resources.working_set.by_key.get('<my pkg name>', None)
        # (I like adding ", None" to gets)
        if disto_obj is not None:
            version_string = disto_obj.version
except Exception:
    # Do something
    pass

2

Abbiamo voluto mettere le meta-informazioni sul nostro pacchetto pypackageryin __init__.py, ma non poteva in quanto ha le dipendenze di terze parti come PJ Eby già sottolineato (vedi la sua risposta e l'avviso per quanto riguarda la condizione di competizione).

Lo abbiamo risolto creando un modulo separato pypackagery_meta.pyche contiene solo le meta informazioni:

"""Define meta information about pypackagery package."""

__title__ = 'pypackagery'
__description__ = ('Package a subset of a monorepo and '
                   'determine the dependent packages.')
__url__ = 'https://github.com/Parquery/pypackagery'
__version__ = '1.0.0'
__author__ = 'Marko Ristin'
__author_email__ = 'marko.ristin@gmail.com'
__license__ = 'MIT'
__copyright__ = 'Copyright 2018 Parquery AG'

quindi importato le meta informazioni in packagery/__init__.py:

# ...

from pypackagery_meta import __title__, __description__, __url__, \
    __version__, __author__, __author_email__, \
    __license__, __copyright__

# ...

e finalmente l'ho usato in setup.py:

import pypackagery_meta

setup(
    name=pypackagery_meta.__title__,
    version=pypackagery_meta.__version__,
    description=pypackagery_meta.__description__,
    long_description=long_description,
    url=pypackagery_meta.__url__,
    author=pypackagery_meta.__author__,
    author_email=pypackagery_meta.__author_email__,
    # ...
    py_modules=['packagery', 'pypackagery_meta'],
 )

È necessario includere pypackagery_metanel pacchetto con l' py_modulesargomento setup. Altrimenti, non è possibile importarlo al momento dell'installazione poiché la distribuzione impacchettata mancherebbe.


1

Semplice e diretto, crea un file chiamato source/package_name/version.pycon i seguenti contenuti:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
__version__ = "2.6.9"

Quindi, sul tuo file source/package_name/__init__.py, importi la versione che altre persone possono usare:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
from .version import __version__

Ora puoi metterlo setup.py

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys

try:
    filepath = 'source/package_name/version.py'
    version_file = open( filepath )
    __version__ ,= re.findall( '__version__ = "(.*)"', version_file.read() )

except Exception as error:
    __version__ = "0.0.1"
    sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )

finally:
    version_file.close()

Testato questo con Python 2.7, 3.3, 3.4, 3.5, 3.6e 3.7su Linux, Windows e Mac OS. Ho usato sul mio pacchetto che ha Test di integrazione e unità per tutte queste piattaforme. Puoi vedere i risultati da .travis.ymle appveyor.ymlqui:

  1. https://travis-ci.org/evandrocoan/debugtools/builds/527110800
  2. https://ci.appveyor.com/project/evandrocoan/pythondebugtools/builds/24245446

Una versione alternativa utilizza il gestore di contesto:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys

try:
    filepath = 'source/package_name/version.py'

    with open( filepath ) as file:
        __version__ ,= re.findall( '__version__ = "(.*)"', file.read() )

except Exception as error:
    __version__ = "0.0.1"
    sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )

Puoi anche utilizzare il codecsmodulo per gestire gli errori Unicode sia su Python 2.7che su3.6

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys
import codecs

try:
    filepath = 'source/package_name/version.py'

    with codecs.open( filepath, 'r', errors='ignore' ) as file:
        __version__ ,= re.findall( '__version__ = "(.*)"', file.read() )

except Exception as error:
    __version__ = "0.0.1"
    sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )

Se stai scrivendo un modulo Python al 100% in C / C ++ usando le estensioni Python C, puoi fare la stessa cosa, ma usando C / C ++ invece di Python.

In questo caso, creare quanto segue setup.py:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys
import codecs
from setuptools import setup, Extension

try:
    filepath = 'source/version.h'

    with codecs.open( filepath, 'r', errors='ignore' ) as file:
        __version__ ,= re.findall( '__version__ = "(.*)"', file.read() )

except Exception as error:
    __version__ = "0.0.1"
    sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )

setup(
        name = 'package_name',
        version = __version__,

        package_data = {
                '': [ '**.txt', '**.md', '**.py', '**.h', '**.hpp', '**.c', '**.cpp' ],
            },

        ext_modules = [
            Extension(
                name = 'package_name',
                sources = [
                    'source/file.cpp',
                ],
                include_dirs = ['source'],
            )
        ],
    )

Che legge la versione dal file version.h:

const char* __version__ = "1.0.12";

Ma non dimenticare di creare MANIFEST.inper includere il version.hfile:

include README.md
include LICENSE.txt

recursive-include source *.h

Ed è integrato nell'applicazione principale con:

#include <Python.h>
#include "version.h"

// create the module
PyMODINIT_FUNC PyInit_package_name(void)
{
    PyObject* thismodule;
    ...

    // https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
    PyObject_SetAttrString( thismodule, "__version__", Py_BuildValue( "s", __version__ ) );

    ...
}

Riferimenti:

  1. errore di file aperto python
  2. Definire un globale in un modulo Python da un'API C.
  3. Come includere i dati del pacchetto con setuptools / distribut?
  4. https://github.com/lark-parser/lark/blob/master/setup.py#L4
  5. Come usare i pacchetti setuptools e ext_modules con lo stesso nome?
  6. È possibile includere sottodirectory usando dist utils (setup.py) come parte dei dati del pacchetto?

1

distribuire pacchetto su server e convenzione di denominazione dei file per i pacchetti di indici:

esempio per la conversione della versione dinamica pip:

  • vincere:

    • test_pkg-1.0.0-CP36-cp36m-win_amd64.whl
    • test_pkg-1.0.0-py3.6-win-amd64.egg
  • Mac:

    • test_pkg-1.0.0-py3.7-MacOSX-10.12-x86_64.egg
    • test_pkg-1.0.0-py3.7-MacOSX-10.12-x86_64.whl
  • linux:
    • test_pkg-1.0.0-CP36-cp36m-linux_x86_64.whl
from setuptools_scm import get_version

def _get_version():

     dev_version = str(".".join(map(str, str(get_version()).split("+")[0]\
            .split('.')[:-1])))

    return dev_version

Trova l'esempio setup.py chiama la versione pip dinamica corrispondente da git commit

setup(
    version=_get_version(),
    name=NAME,
    description=DESCRIPTION,
    long_description=LONG_DESCRIPTION,
    classifiers=CLASSIFIERS,

# add few more for wheel wheel package ...conversion

)

0

Sto usando una variabile d'ambiente come di seguito

VERSIONE = 0.0.0 python setup.py sdist bdist_wheel

In setup.py


import os

setup(
    version=os.environ['VERSION'],
    ...
)

Per un controllo di coerenza con la versione del packer, sto usando lo script seguente.

PKG_VERSION=`python -c "import pkg; print(pkg.__version__)"`
if [ $PKG_VERSION == $VERSION ]; then
    python setup.py sdist bdist_wheel
else
    echo "Package version differs from set env variable"
fi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.