패키지의 setup.py (setuptools)에 정의 된 버전을 얻으려면 어떻게해야합니까?


답변:


246

이미 설치된 배포의 질문 버전 문자열

런타임에 패키지 내부에서 버전을 검색하려면 (질문이 실제로 묻는 것) 다음을 사용할 수 있습니다.

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

설치 중 사용할 저장소 버전 문자열

다른 방법으로 돌아가고 싶다면 (여기서 다른 답변 작성자가 요청한 것으로 보이는 것처럼 보임) 버전 문자열을 별도의 파일에 넣고에서 해당 파일의 내용을 읽으십시오 setup.py.

패키지에서 한 __version__줄로 version.py를 만든 다음을 사용하여 setup.py에서 읽어서 setup.py 네임 스페이스에서 execfile('mypackage/version.py')설정할 수 __version__있습니다.

버전 문자열에 액세스해야하는 모든 Python 버전 및 비 Python 언어에서 작동하는 훨씬 간단한 방법을 원할 경우 :

버전 문자열을 일반 텍스트 파일 (예 : eg)의 유일한 내용으로 저장하고 VERSION그 동안 해당 파일을 읽습니다 setup.py.

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

그러면 동일한 VERSION파일이 다른 프로그램, 심지어 비 Python 파일에서도 동일 하게 작동하며 모든 프로그램에 대해 한 곳에서 버전 문자열 만 변경하면됩니다.

설치 중 경쟁 조건에 대한 경고

그건 그렇고, 다른 대답에서 제안 된 것처럼 setup.py에서 패키지를 가져 오지 마십시오. 패키지의 종속성이 이미 설치되어 있기 때문에 효과가있는 것처럼 보이지만 패키지의 새로운 사용자에게 혼란을 줄 수 있습니다 종속성을 수동으로 설치하지 않으면 패키지를 설치할 수 없습니다.


1
이것은 가장 좋은 대답입니다. 패키지에서 버전을 가져 오기 위해 setup.py가 필요한 경우 execfile을 사용하는 것이 가장 좋습니다.
trinth

2
execfile정말 잘 작동하지만 ... (슬프게도) 파이썬 3에서는 작동하지 않습니다.
medmunds

9
... OK, 파이썬 2 3 사용 with open('mypackage/version.py') as f: exec(f.read())대신에 execfile('mypackage/version.py'). ( stackoverflow.com/a/437857/647002에서 )
medmunds

5
wreak havoc 부분은 반드시 사실이 아닙니다 ... 패키지 의 init .py 파일에 코드 가져 오기 종속성이 (직접 또는 간접적으로)있는 경우에만 혼란을 초래합니다.
Pykler

2
django 가 setup.py에서 __import__ 호출 수행한다고 언급 할 가치가 있습니다. '__import__'대 'import'가 이것을 안전하게합니까? 문제를 일으키는 것으로 보이지 않습니다.
user1978019

33

예시 연구 : mymodule

이 구성을 상상해보십시오.

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

그런 다음 의존성이 있고 setup.py다음과 같은 일반적인 시나리오를 상상하십시오 .

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

그리고 예 __init__.py:

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

그리고 예를 들면 myclasses.py:

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

문제 # 1 : 가져 오기 mymodule 설정 중

귀하의 경우 setup.py수입은 mymodule다음 설치하는 동안 당신은 일 가능성을 얻을 것ImportError . 패키지에 종속성이있는 경우 매우 일반적인 오류입니다. 패키지에 내장 이외의 다른 종속성이없는 경우 안전 할 수 있습니다. 그러나 이것은 좋은 습관이 아닙니다. 그 이유는 미래에 대비할 수 없기 때문입니다. 내일 코드에서 다른 종속성을 사용해야한다고 말하십시오.

문제 # 2 : 나의 어디에 __version__ ?

당신이 하드 코딩하는 경우 __version__setup.py그것은 당신이 당신의 모듈에 출시 할 것이라는 버전과 일치하지 않을 수 있습니다. 일관성을 유지하려면 한 장소에 놓고 필요할 때 같은 장소에서 읽으십시오. 사용import 하면 문제 # 1이 발생할 수 있습니다.

해결책 : à la setuptools

당신의 조합을 사용 open, exec그리고에 대한 딕셔너리를 제공하는 exec추가 변수 :

# 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__'],
    ...)

그리고 mymodule/version.py버전 을 공개하십시오 :

__version__ = 'some.semantic.version'

이 방법으로, 버전은 모듈과 함께 제공되며, 설치 중에 종속성이없는 모듈을 가져 오려고 시도하는 동안 문제가 발생하지 않습니다 (아직 설치해야 함).


2
허용되는 종속성에만 의존하기 때문에 가장 합리적인 솔루션처럼 보입니다.
Dogweather

패키지 버전의 개념은에서 setup.py 파일 다른에 정의되어 버전 ?
변수

16

가장 좋은 방법은 __version__제품 코드에서 정의한 다음 거기에서 setup.py로 가져 오는 것입니다. 이를 통해 실행중인 모듈에서 읽을 수있는 값을 정의 할 수있는 위치는 한 곳뿐입니다.

setup.py의 값이 설치되어 있지 않으며 설치 후 setup.py가 붙어 있지 않습니다.

coverage.py에서 내가 한 일 (예 :)

# coverage/__init__.py
__version__ = "3.2"


# setup.py
from coverage import __version__

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

업데이트 (2017) : coverage.py가 더 이상 버전을 가져 오기 위해 가져 오지 않습니다. 제품 코드는 setup.py가 설치되어 있기 때문에 아직 설치되지 않은 종속성을 가져 오려고하기 때문에 고유 코드를 가져 오면 제거 할 수 있습니다.


4
@Evan : 나는 당신이 무엇을 얻는 지 확신하지 못한다. 파일이 들어있는 파일이 __version__어떤 식 으로든 손상된 경우 가져 오기도 손상됩니다. 파이썬은 원하는 문장만을 해석하는 방법을 모릅니다. @pjeby가 맞습니다. 모듈이 다른 모듈을 가져와야 할 경우 아직 설치되지 않았을 수 있으며 혼란 스러울 수 있습니다. 이 기술은 수입품이 다른 수입품의 긴 체인을 유발하지 않도록주의 할 때 효과적입니다.
Ned Batchelder 2016 년

1
@ Ned Batchelder 소스 파일에서 가져 오기 전에 버전을 넣고 '모듈 가져 오기 버전에서'만 사용하면 필요한 것보다 더 많은 소스 파일이 표시되지 않습니다. 게다가, 누가 깨진 코드를 공개할까요? 패키지에 종속성이 필요한 경우 setuptools를 사용하거나 연말에 distutils2가 릴리스 될 때까지 기다리십시오.
Evan Plaice

15
@Evan, 죄송합니다. 부분 파일을 가져 오는 데 잘못되었습니다. 긴 모듈의 끝에 print 문을 넣고 파일에 정의 된 첫 번째 변수를 가져 오십시오. 인쇄 문이 실행됩니다.
Ned Batchelder 2016 년

23
나는 이것에 빠졌지 만 @pjeby는 전적으로 옳다 : "그런데, 다른 대답에서 제안 된 것처럼 setup.py에서 패키지를 가져 오지 마십시오 : 이미 패키지의 종속성이 설치되어 있기 때문에 효과가있는 것 같습니다. ), 그러나 패키지를 처음 사용하는 사용자는 먼저 종속성을 수동으로 설치하지 않으면 패키지를 설치할 수 없으므로 패키지 사용자를 혼란스럽게 할 것입니다. " 네드, 답변에 경고를 추가 하시겠습니까?
Dr. Jan-Philip Gehrcke 8

1
PyPI에 setup.py 파일을 업로드 할 때 @ Jan-PhilipGehrcke와 같이 pip install <packagename>다음과 같은 오류가 발생 ImportError: No module named <packagename>합니다. 패키지가 아직 설치되지 않은 환경에서 이와 같은 setup.py 파일을 실행할 수 없다는 것을 독자들에게 경고하십시오!
호브

14

귀하의 질문은 약간 모호하지만, 당신이 묻는 것은 그것을 지정하는 방법이라고 생각합니다.

다음 __version__과 같이 정의해야합니다 .

__version__ = '1.4.4'

그런 다음 setup.py가 방금 지정한 버전에 대해 알고 있음을 확인할 수 있습니다.

% ./setup.py --version
1.4.4

9

나는이 답변에 만족하지 못했습니다 ... setuptools를 필요로하지 않고 단일 변수에 대해 별도의 모듈을 만들지 않기 때문에 이것들을 생각해 냈습니다.

메인 모듈이 pep8 스타일이고 확실하게 유지 될 때 :

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

추가로주의를 기울이고 실제 파서를 사용하려는 경우 :

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는 다소 낡은 모듈이므로 조금 추한 경우에는 문제가되지 않습니다.


업데이트 : 재미있었습니다. 최근 몇 년 동안이에서 멀어지고 패키지에서 별도의 파일을 사용하기 시작했습니다 meta.py. 나는 자주 변경하고 싶을 정도로 많은 메타 데이터를 거기에 넣었다. 따라서 하나의 가치 만이 아닙니다.


+1. 상대적으로 간단하고 버전 번호를 한 곳에 유지하고 파일을 포함하기 위해 별도의 파일이 필요하지 않으며 setup.py에 대한 파이썬 모듈의 가져 오기 종속성을 강요하지 않습니다. setup.py처럼 수명이 짧은 프로그램의 컨텍스트 관리자를 귀찮게하지 않을 것입니다.
ʇsәɹoɈ

정규식을 사용하는 것보다 훨씬 좋습니다. 감사합니다. 당신은 또한 소스 등을 자동으로 채우기 위해 ast.get_docstring()일부와 함께 사용할 수 있습니다 . 동기화해야 할 한 가지 적은.split('\n')[0].strip()description
손실

4

소스 트리에서 파일을 작성하십시오 (예 : yourbasedir / yourpackage / _version.py). 해당 파일에 다음과 같이 한 줄의 코드 만 포함 시키십시오.

__version__ = "1.1.0-r4704"

그런 다음 setup.py에서 해당 파일을 열고 다음과 같이 버전 번호를 구문 분석하십시오.

verstr = "알 수 없음"
시험:
    verstrline = open ( 'yourpackage / _version.py', "rt"). read ()
EnvironmentError를 제외하고 :
    pass # 좋아요, 버전 파일이 없습니다.
그밖에:
    VSRE = r "^ __ version__ = [ '\"] ([^'\ "] *) [ '\"] "
    mo = 재검색 (VSRE, verstrline, re.M)
    mo 인 경우 :
        verstr = mo.group (1)
    그밖에:
        런타임 오류 발생 ( "package / _version.py에서 버전을 찾을 수 없음")

마지막으로 yourbasedir/yourpackage/__init__.pyimport _version에서 다음과 같이하십시오.

__version__ = "알 수 없음"
시험:
    _version import __version__에서
ImportError를 제외하고 :
    # _version.py가없는 트리에서 실행 중이므로 버전이 무엇인지 모릅니다.
    통과하다

이를 수행하는 코드의 예는 내가 관리하는 "pyutil"패키지입니다. (PyPI 또는 Google 검색 참조-stackoverflow로 인해이 답변에 하이퍼 링크가 포함되지 않습니다.)

@pjeby는 자신의 setup.py에서 패키지를 가져 와서는 안됩니다. 새로운 파이썬 인터프리터를 만들고 setup.py를 먼저 실행하여 테스트 할 때 작동 python setup.py하지만 작동하지 않는 경우가 있습니다. 의 때문 import youpackage"yourpackage"라는 이름의 디렉토리에 대한 현재 작업 디렉토리를 읽을 것을 의미하지 않는다, 현재에 보는 의미 sys.modules핵심 "yourpackage"에 대한 한 후이없는 경우 다양한 일을 할 수 있습니다. 따라서 python setup.py비어 sys.modules있고 비어 있기 때문에 항상 작동 하지만 일반적으로는 작동하지 않습니다.

예를 들어 py2exe가 응용 프로그램을 패키징하는 과정의 일부로 setup.py를 실행중인 경우 어떻게해야합니까? 패키지가 버전 번호를 가져 오기 때문에 py2exe가 패키지에 잘못된 버전 번호를 넣는 경우를 보았습니다.import myownthingsetup.py에 있지만 py2exe 실행 중에 해당 패키지의 다른 버전을 이전에 가져 왔습니다. 마찬가지로 setuptools, easy_install, distribution 또는 distutils2가 사용자에 따라 다른 패키지를 설치하는 프로세스의 일부로 패키지를 빌드하려고하면 어떻게합니까? 그런 다음 setup.py를 평가할 때 패키지를 가져올 수 있는지 또는이 Python 인터프리터 수명 동안 가져온 패키지 버전이 있는지 또는 패키지를 가져 오기 위해 다른 패키지를 먼저 설치해야하는지 여부 부작용이 있거나 결과가 바뀔 수 있습니다. py2exe 및 setuptools와 같은 도구에서 setup.py가 버전 번호를 찾기 위해 패키지 자체를 가져 오기 때문에 py2exe 및 setuptools와 같은 도구에 문제를 일으키는 Python 패키지를 재사용하려고 시도하는 데 어려움을 겪었습니다.

그건 그렇고,이 기술은 yourpackage/_version.py수정 제어 기록을 읽고 수정 제어 기록의 최신 태그를 기반으로 버전 번호를 작성하는 등 자동으로 파일 을 자동으로 생성하는 도구와 함께 잘 작동 합니다. 다음은 darcs에 해당하는 도구입니다. http://tahoe-lafs.org/trac/darcsver/browser/trunk/README.rst 여기 git에 대해 동일한 작업을 수행하는 코드 스 니펫이 있습니다. http : // github .com / warner / python-ecdsa / blob / 0ed702a9d4057ecf33eea969b8cf280eaccd89a1 / setup.py # L34


3

정규식을 사용하고 메타 데이터 필드에 따라 다음과 같은 형식을 갖도록 작동해야합니다.

__fieldname__ = 'value'

setup.py의 시작 부분에서 다음을 사용하십시오.

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

그런 다음 스크립트에서 메타 데이터를 다음과 같이 사용할 수 있습니다.

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

제가 위에서 말했듯이, 단지 :) str.split를 사용
의 Éric 아라 우호

맙소사 파이썬에서 파이썬을 파싱하고 있습니까? 최소한 eval (), child를 사용하십시오.
slacy

3
불충분 한 조언 슬픔, 평가는 너무 쉽게 피해야합니다.
Gringo Suave

3

다음과 같은 구조로 :

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

어디 version.py가 포함되어 있습니다 :

__version__ = 'version_string'

setup.py 에서이를 수행 할 수 있습니다 .

import sys

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

from version import __version__

이것은 mymodule / __ init__.py에있는 의존성에 아무런 문제를 일으키지 않습니다.


2

파일 가져 오기 (및 코드 실행)를 피하기 위해 파일을 구문 분석 version하고 구문 트리에서 속성을 복구 할 수 있습니다 .

# 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

이 코드는 모듈 반환의 최상위 수준에서 __version__또는 VERSION할당이 문자열 값임을 찾으려고 시도 합니다. 오른쪽은 문자열 또는 튜플 일 수 있습니다.


3
그것은 영리하고 복잡해 보입니다 :) 하나의 할당을 포함하는 _version.py 파일을 가지고 open-read-str.split으로 구문 분석하는 것이 더 간단합니다.
Éric Araujo

게시 해 주셔서 감사합니다. 이 상황에서는 너무 복잡하지만 문제에 어떻게 접근 할 수 있는지 이해하는 데 매우 도움이됩니다. 버전 번호를 한 곳에 유지하고 파일을 포함하기 위해 별도의 파일이 필요하지 않으며 설정 스크립트에 파이썬 모듈의 가져 오기 종속성을 강요하지 않습니다.
ʇsәɹoɈ

2

고양이를 깎는 방법은 수천 가지입니다. 여기 내 것이 있습니다 :

# 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

@ gringo-suave에서 https://stackoverflow.com/a/12413800 정리 :

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

이제 이것은 거칠고 정제가 필요합니다 (내가 놓친 pkg_resources에서 발견되지 않은 회원 전화가있을 수도 있습니다). 그러나 왜 이것이 작동하지 않는지 또는 아무도 그것을 제안하지 않은 이유는 알지 못합니다 (구글링은 이것은 파이썬 2.x이므로 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

패키지 pypackagery에 대한 메타 정보를 넣고 싶었습니다.__init__.py PJ Eby가 이미 지적한 것처럼 타사 종속성을 가지고 있기 때문에 (그의 대답과 경쟁 조건에 대한 경고 참조).

메타 정보 pypackagery_meta.py 포함 된 별도의 모듈 을 만들어서 해결했습니다 .

"""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'

그런 다음 메타 정보를 다음으로 가져 왔습니다 packagery/__init__.py.

# ...

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

# ...

그리고 마침내 그것을 사용했습니다 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'],
 )

설치 인수 pypackagery_meta를 사용하여 패키지에 포함시켜야합니다 py_modules. 그렇지 않으면 패키지 배포에 부족하므로 설치시 가져올 수 없습니다.


1

간단하고 직설적으로 source/package_name/version.py다음 내용으로 불리는 파일을 만듭니다 .

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

그런 다음 파일 source/package_name/__init__.py에서 다른 사람이 사용할 수있는 버전을 가져옵니다.

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

자, 이것을 입을 수 있습니다 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()

파이썬이 테스트 2.7, 3.3, 3.4, 3.5, 3.63.7리눅스, 윈도우와 맥 OS에. 모든 플랫폼에 대한 통합 및 단위 테스트가있는 패키지를 사용했습니다. 당신의 결과를 볼 수 .travis.ymlappveyor.yml여기를 :

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

대체 버전은 컨텍스트 관리자를 사용하고 있습니다.

#!/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 ) )

또한 codecs모듈을 사용하여 파이썬 2.7과 유니 코드 모두에서 유니 코드 오류를 처리 할 수 있습니다3.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 ) )

Python C Extensions를 사용하여 C / C ++에서 Python 모듈을 100 % 작성하는 경우 동일한 작업을 수행 할 수 있지만 Python 대신 C / C ++를 사용합니다.

이 경우 다음을 작성하십시오 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'],
            )
        ],
    )

파일에서 버전을 읽는 것 version.h:

const char* __version__ = "1.0.12";

그러나 파일 MANIFEST.in을 포함하도록 version.h파일 을 작성하는 것을 잊지 마십시오 .

include README.md
include LICENSE.txt

recursive-include source *.h

그리고 다음과 같이 기본 응용 프로그램에 통합됩니다.

#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__ ) );

    ...
}

참고 문헌 :

  1. 파이썬 파일 열기 오류
  2. C API에서 Python 모듈로 전역 정의
  3. setuptools / distribute에 패키지 데이터를 포함시키는 방법은 무엇입니까?
  4. https://github.com/lark-parser/lark/blob/master/setup.py#L4
  5. setuptools 패키지와 ext_modules를 같은 이름으로 사용하는 방법은 무엇입니까?
  6. 패키지 데이터의 일부로 dist utils (setup.py)를 사용하여 하위 디렉토리를 포함 할 수 있습니까?

1

인덱스 패키지를 위해 패키지를 서버에 배치하고 파일 이름 지정 규칙을 작성하십시오.

pip 동적 버전 변환의 예 :

  • 승리:

    • test_pkg-1.0.0-cp36-cp36m-win_amd64.whl
    • test_pkg-1.0.0-py3.6-win-amd64.egg
  • 맥:

    • 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
  • 리눅스 :
    • 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

샘플 setup.py를 찾으십시오 .git commit에서 동적 pip 버전 일치를 호출합니다.

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

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

)

0

아래와 같이 환경 변수를 사용하고 있습니다

VERSION = 0.0.0 python setup.py sdist bdist_wheel

setup.py에서


import os

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

패커 버전과의 일관성 검사를 위해 아래 스크립트를 사용하고 있습니다.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.