레퍼런스 요건setuptools setup.py 파일의 install_displays kwarg에 대한 txt
는 나나 a a a가 있다requirements.txt
Travis-CI 。 것 .requirements.txt
★★★★★★★★★★★★★★★★★」setup.py
그래서 저는 파일핸들을 전달하고 싶었습니다.install_requires
setuptools.setup
.
이게 가능합니까?그렇다면 어떻게 하면 좋을까요?
제 사진이 .requirements.txt
삭제:
guessit>=0.5.2
tvdb_api>=1.8.2
hachoir-metadata>=1.3.3
hachoir-core>=1.3.3
hachoir-parser>=1.3.4
보기에는 것 requirements.txt
★★★★★★★★★★★★★★★★★」setup.py
는 우스꽝스러운 복제품이지만 형태는 비슷하지만 의도한 기능은 매우 다르다는 것을 이해하는 것이 중요합니다.
패키지 작성자의 목표는 종속성을 지정할 때 "이 패키지를 어디에 설치하든 이 패키지가 작동하기 위해 필요한 다른 패키지입니다."라고 말하는 것입니다.
한편, 도입의 작성자(다른 때에 같은 사람일 가능성이 있습니다)는, 「이것이, 집합해 테스트한 패키지의 리스트이며, 인스톨 할 필요가 있는 패키지의 리스트입니다」라고 하는 다른 일을 하고 있습니다.
패키지 작성자는 다양한 시나리오에 대해 기술합니다.왜냐하면 패키지 작성자는 자신이 모르는 방법으로 사용할 수 있도록 작업하고 있으며 패키지와 함께 어떤 패키지가 설치될지 알 수 없기 때문입니다.좋은 네이버가 되어 다른 패키지와의 의존 버전 경합을 피하기 위해 가능한 한 광범위한 의존 버전 범위를 지정해야 합니다. 바로 런 this this입니다.install_requires
setup.py
전개 작성자는, 특정의 컴퓨터에 인스톨 되어 있는 애플리케이션 또는 서비스의 단일 인스턴스라고 하는, 매우 다른, 매우 구체적인 목적을 위해서 기술하고 있습니다.전개를 정밀하게 제어하고 적절한 패키지가 테스트 및 전개되도록 하기 위해 전개 작성자는 의존관계 및 의존관계 등 설치할 모든 패키지의 정확한 버전과 소스 위치를 지정해야 합니다.이 사양을 사용하면 배포를 여러 시스템에 반복적으로 적용하거나 테스트 시스템에서 테스트할 수 있으며 배포 작성자는 매번 동일한 패키지가 배포된다는 확신을 가질 수 있습니다. 바로 게 this this this this this this this this this 。requirements.txt
보시다시피 이 두 가지가 모두 패키지와 버전의 큰 목록처럼 보이지만 이 두 가지는 매우 다른 역할을 합니다.은 '이렇게 하는 것'입니다.requirements.txt
모든 다양한 요구 사항에 의해 제기되는 "질문"에 대한 "답변"입니다.setup.py
이렇게 으로 쓰는 보다 pip에게 pip을 다 경우가 setup.py
내의 을 검색하여를 찾은 후 는 "패키지 목록"입니다).pip freeze
이름이 유래합니다).
여기서 얻을 수 있는 것은 다음과 같습니다.
setup.py
는 아직 동작 가능한 가장 느슨한 의존관계 버전을 선언해야 합니다.이 패키지의 역할은 특정 패키지가 무엇을 사용할 수 있는지를 말하는 것입니다.requirements.txt
는 전체 설치 작업을 정의하는 배포 매니페스트이며, 하나의 패키지에 연결된 것으로 간주해서는 안 됩니다.이 패키지의 역할은 전개가 작동하는 데 필요한 모든 패키지의 완전한 목록을 선언하는 것입니다.- 이 두 가지는 존재하는 내용과 이유가 매우 다르기 때문에 단순히 하나를 다른 것으로 복사하는 것은 가능하지 않습니다.
참고 자료:
- install_requires와 Python 패키징 사용자 가이드의 Requirements 파일을 비교합니다.
''를 '는 '의존속관계는요?setup.py
으로 점으로 하다. 으로 점으로 표시하다..
인 : 。requirements.txt
★★★★★★ 。
할 수 .requirements.txt
의한 경우)에 다음의 )을 합니다.pip 9.0.1
install_reqs = parse_requirements('requirements.txt', session='hack')
특히 6.0보다 오래된 이전 버전의 pip에서는 이를 실현하기 위해 사용할 수 있는 퍼블릭 API가 있습니다.요건 파일에는 코멘트를 포함할 수 있습니다(#
파일 )을 포함할 수 --requirement
★★★★★★★★★★★★★★★★★」-r
「 」를 는, 「 」를 참조해 주세요.requirements.txt
는 pip parser:는 parser:는 pip parser를 사용할 수.
from pip.req import parse_requirements
# parse_requirements() returns generator of pip.req.InstallRequirement objects
install_reqs = parse_requirements(<requirements_path>)
# reqs is a list of requirement
# e.g. ['django==1.5.1', 'mezzanine==1.4.6']
reqs = [str(ir.req) for ir in install_reqs]
setup(
...
install_requires=reqs
)
파일 핸들을 사용할 수 없습니다.install_requires
인수에는 문자열 또는 문자열 목록만 사용할 수 있습니다.
수 .install_requires
.
import os
from setuptools import setup
with open('requirements.txt') as f:
required = f.read().splitlines()
setup(...
install_requires=required,
...)
형식을 이은 "pip"을 가 있는 이 됩니다.이것은, 유저에게 필요한 경우에 한해 유효합니다.setup.py
일부 의 출력을 하는 등 더 제약을 .pip freeze
패키지 세트 전체를 기존의 동작 버전으로 프리즈합니다.않은 " " "만합니다.setup.py
requirements.txt
1번, 1번, 1번, 1번, 1번, 1번.
.
하며, 이 입니다.setup.py
같은 디렉토리에 있습니다.
질문에 대한 정확한 답변은 아니지만, 이 문제에 대한 좋은 인식을 위해 https://caremad.io/2013/07/setup-vs-requirement/에 있는 Donald Stufft의 블로그 포스트를 추천합니다.나는 그것을 매우 성공적으로 사용해 왔다.
로 말하면, 요,,,requirements.txt
아니다setup.py
대체 수단이지만, 도입 보완 수단입니다. 를 에 합니다.setup.py
를 설정합니다.requirements.txt
개발, 테스트 또는 프로덕션용 패키지 종속성의 특정 버전을 가져올 수 있습니다.
예: 레포에 포함된 패키지deps/
:
# fetch specific dependencies
--no-index
--find-links deps/
# install package
# NOTE: -e . for editable mode
.
의 pip을 합니다.setup.py
에 된 특정 합니다.install_requires
이중성이 없고 두 유물 모두 목적이 보존되어 있습니다.
「」를 사용합니다.parse_requirements
되지 않기 때문에 .pip API는 공개 문서화되어 있지 .1. 있기 는 breakpip 1.6이 될 .
way a a a a 의 중복을 없애는 보다 신뢰성 높은 방법setup.py
★★★★★★★★★★★★★★★★★」requirements.txt
''는요, ''를 구체적으로 예요.setup.py
다음에 리 and를 붙입니다.-e .
의 에 your에requirements.txt
일일 the the の of of of の of of file file file file file file file file file file file file file file의 일부 정보pip
왜 이것이 더 나은 방법인지에 대한 개발자는 https://caremad.io/blog/setup-vs-requirement/에서 구할 수 있습니다.
위의 다른 답변의 대부분은 현재 버전의 pip API에서 작동하지 않습니다.현재 버전의 pip (작성 시 6.0.8, 7.1.2에서도 동작)를 사용하는 올바른* 방법을 다음에 나타냅니다.pip - V)로 버전을 확인할 수 있습니다.
from pip.req import parse_requirements
from pip.download import PipSession
install_reqs = parse_requirements(<requirements_path>, session=PipSession())
reqs = [str(ir.req) for ir in install_reqs]
setup(
...
install_requires=reqs
....
)
* 현재 pip에서 parse_requirements를 사용하는 방법이기 때문에 정답입니다.위의 포스터에서 말한 것처럼 pip은 API를 유지하지 않기 때문에 여전히 최선의 방법은 아닐 수 있습니다.
나는 그런 일을 하는 것을 추천하지 않는다. 번 install_requires
★★★★★★★★★★★★★★★★★」requirements.txt
같은 리스트가 되어서는 안 됩니다.그러나 pip의 개인 내부 API와 관련된 오해의 소지가 많은 답변이 있기 때문에 보다 건전한 대안을 검토할 가치가 있을 것입니다.
간단한 합니다.requirements.txt
셋업툴에서 파일을 작성하다 setup.py
스크립트(pip 없음)setuptools 프로젝트에 필요한 도구가 이미 최상위 패키지에 포함되어 있습니다.pkg_resources
.
대략 다음과 같습니다.
#!/usr/bin/env python3
import pathlib
import pkg_resources
import setuptools
with pathlib.Path('requirements.txt').open() as requirements_txt:
install_requires = [
str(requirement)
for requirement
in pkg_resources.parse_requirements(requirements_txt)
]
setuptools.setup(
install_requires=install_requires,
)
다시 말씀드리지만, 이것은 단순한 경우에만 작동합니다.requirements.txt
파일 처리 방법에 대한 자세한 내용은 문서 페이지의 요구 사항 분석을 참조하십시오.즉, 각 행은 유효한 PEP 508 요건이어야 합니다.실제로 pip에 고유한 표기는 지원되지 않으므로 장애가 발생합니다.
주의사항
이미 설명한 바와 같이 이는 권장되지 않습니다.requirements.txt
파일 및 "설치 종속성" 목록은 서로 다른 두 가지 개념이며 서로 호환되지 않습니다.
만약에 setup.py
하다requirements.txt
에 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이.requirements.txt
파일이 「소스 배포」(sdistribution)(sdist)에 포함되어 있지 않으면, 인스톨에 실패합니다.
62.6 부터는 setuptools에서도 이와 쓸 수 .setup.cfg
:
[options]
install_requires = file: requirements.txt
른른른 altern altern alternpyproject.toml
:
[project]
dynamic = ["dependencies"]
[tool.setuptools.dynamic]
dependencies = requirements.txt
위와 같은 경고 문구가 적용됩니다.
- 매우 단순한 파일만 지원됩니다.
- 파일을 sdist에 추가해야 합니다.
또, 현재로서는 「베타」기능으로 간주되고 있습니다.
주의:
- 기타 답변도 참조하십시오.https://stackoverflow.com/a/59971236/11138259
- https://caremad.io/posts/2013/07/setup-vs-requirement/
- https://setuptools.pypa.io/en/latest/history.html#v62-6-0
트래비스 하면 '어느 정도'가 되지 않게 됩니다.requirements.txt
예를 들어 다음과 같습니다.
language: python
python:
- "2.7"
- "2.6"
install:
- pip install -q -e .
script:
- python runtests.py
에서는 요건 을 에서 .setup.py
Dmitiry S의 답변을 변형한 것입니다.이 답변은 Python 3.6+와만 호환됩니다.
D.S.에 따르면requirements.txt
인 요건을 버전 할 수 .단, '버전 번호'는 다음과 같습니다.setup.py
는 버전 범위가 느슨한 추상 요건을 문서화할 수 있습니다.
는 저의 발췌장.setup.py
.
import distutils.text_file
from pathlib import Path
from typing import List
def _parse_requirements(filename: str) -> List[str]:
"""Return requirements from requirements file."""
# Ref: https://stackoverflow.com/a/42033122/
return distutils.text_file.TextFile(filename=str(Path(__file__).with_name(filename))).readlines()
setup(...
install_requires=_parse_requirements('requirements.txt'),
...)
:distutils.text_file.TextFile
을 사용하다 제 , 하기 를 밟을 는 없는 것 .
from pip.req import parse_requirements
는 동작합니다. 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.
def parse_requirements(requirements):
with open(requirements) as f:
return [l.strip('\n') for l in f if l.strip('\n') and not l.startswith('#')]
reqs = parse_requirements(<requirements_path>)
setup(
...
install_requires=reqs,
...
)
다음 인터페이스는 pip 10에서 폐지되었습니다.
from pip.req import parse_requirements
from pip.download import PipSession
그래서 단순한 텍스트 구문 분석으로 전환했습니다.
with open('requirements.txt', 'r') as f:
install_reqs = [
s for s in [
line.split('#', 1)[0].strip(' \t\n') for line in f
] if s != ''
]
사용자에게 pip 설치를 강요하지 않으려면 다음과 같이 동작을 에뮬레이트할 수 있습니다.
import sys
from os import path as p
try:
from setuptools import setup, find_packages
except ImportError:
from distutils.core import setup, find_packages
def read(filename, parent=None):
parent = (parent or __file__)
try:
with open(p.join(p.dirname(parent), filename)) as f:
return f.read()
except IOError:
return ''
def parse_requirements(filename, parent=None):
parent = (parent or __file__)
filepath = p.join(p.dirname(parent), filename)
content = read(filename, parent)
for line_number, line in enumerate(content.splitlines(), 1):
candidate = line.strip()
if candidate.startswith('-r'):
for item in parse_requirements(candidate[2:].strip(), filepath):
yield item
else:
yield candidate
setup(
...
install_requires=list(parse_requirements('requirements.txt'))
)
parse_requirements
동!!
해 주세요.pip.req.parse_requirements
밑줄이 대시로 변경됩니다.내가 발견하기 전 며칠간은 이것이 나를 화나게 했다.★★★★
from pip.req import parse_requirements # tested with v.1.4.1
reqs = '''
example_with_underscores
example-with-dashes
'''
with open('requirements.txt', 'w') as f:
f.write(reqs)
req_deps = parse_requirements('requirements.txt')
result = [str(ir.req) for ir in req_deps if ir.req is not None]
print result
생산하다
['example-with-underscores', 'example-with-dashes']
재사용 가능한 기능을 만들었습니다.실제로 요건 파일의 디렉토리 전체를 해석하여 extra_require로 설정합니다.
항상 최신 정보를 입수할 수 있습니다.https://gist.github.com/akatrevorjay/293c26fefa24a7b812f5
import glob
import itertools
import os
# This is getting ridiculous
try:
from pip._internal.req import parse_requirements
from pip._internal.network.session import PipSession
except ImportError:
try:
from pip._internal.req import parse_requirements
from pip._internal.download import PipSession
except ImportError:
from pip.req import parse_requirements
from pip.download import PipSession
def setup_requirements(
patterns=[
'requirements.txt', 'requirements/*.txt', 'requirements/*.pip'
],
combine=True):
"""
Parse a glob of requirements and return a dictionary of setup() options.
Create a dictionary that holds your options to setup() and update it using this.
Pass that as kwargs into setup(), viola
Any files that are not a standard option name (ie install, tests, setup) are added to extras_require with their
basename minus ext. An extra key is added to extras_require: 'all', that contains all distinct reqs combined.
Keep in mind all literally contains `all` packages in your extras.
This means if you have conflicting packages across your extras, then you're going to have a bad time.
(don't use all in these cases.)
If you're running this for a Docker build, set `combine=True`.
This will set `install_requires` to all distinct reqs combined.
Example:
>>> import setuptools
>>> _conf = dict(
... name='mainline',
... version='0.0.1',
... description='Mainline',
... author='Trevor Joynson <github@trevor.joynson,io>',
... url='https://trevor.joynson.io',
... namespace_packages=['mainline'],
... packages=setuptools.find_packages(),
... zip_safe=False,
... include_package_data=True,
... )
>>> _conf.update(setup_requirements())
>>> # setuptools.setup(**_conf)
:param str pattern: Glob pattern to find requirements files
:param bool combine: Set True to set install_requires to extras_require['all']
:return dict: Dictionary of parsed setup() options
"""
session = PipSession()
# Handle setuptools insanity
key_map = {
'requirements': 'install_requires',
'install': 'install_requires',
'tests': 'tests_require',
'setup': 'setup_requires',
}
ret = {v: set() for v in key_map.values()}
extras = ret['extras_require'] = {}
all_reqs = set()
files = [glob.glob(pat) for pat in patterns]
files = itertools.chain(*files)
for full_fn in files:
# Parse
reqs = {
str(r.req)
for r in parse_requirements(full_fn, session=session)
# Must match env marker, eg:
# yarl ; python_version >= '3.0'
if r.match_markers()
}
all_reqs.update(reqs)
# Add in the right section
fn = os.path.basename(full_fn)
barefn, _ = os.path.splitext(fn)
key = key_map.get(barefn)
if key:
ret[key].update(reqs)
extras[key] = reqs
extras[barefn] = reqs
if 'all' not in extras:
extras['all'] = list(all_reqs)
if combine:
extras['install'] = ret['install_requires']
ret['install_requires'] = list(all_reqs)
def _listify(dikt):
ret = {}
for k, v in dikt.items():
if isinstance(v, set):
v = list(v)
elif isinstance(v, dict):
v = _listify(v)
ret[k] = v
return ret
ret = _listify(ret)
return ret
__all__ = ['setup_requirements']
if __name__ == '__main__':
reqs = setup_requirements()
print(reqs)
또 다른 가능한 해결책...
def gather_requirements(top_path=None):
"""Captures requirements from repo.
Expected file format is: requirements[-_]<optional-extras>.txt
For example:
pip install -e .[foo]
Would require:
requirements-foo.txt
or
requirements_foo.txt
"""
from pip.download import PipSession
from pip.req import parse_requirements
import re
session = PipSession()
top_path = top_path or os.path.realpath(os.getcwd())
extras = {}
for filepath in tree(top_path):
filename = os.path.basename(filepath)
basename, ext = os.path.splitext(filename)
if ext == '.txt' and basename.startswith('requirements'):
if filename == 'requirements.txt':
extra_name = 'requirements'
else:
_, extra_name = re.split(r'[-_]', basename, 1)
if extra_name:
reqs = [str(ir.req) for ir in parse_requirements(filepath, session=session)]
extras.setdefault(extra_name, []).extend(reqs)
all_reqs = set()
for key, values in extras.items():
all_reqs.update(values)
extras['all'] = list(all_reqs)
return extras
그리고 나서...
reqs = gather_requirements()
install_reqs = reqs.pop('requirements', [])
test_reqs = reqs.pop('test', [])
...
setup(
...
'install_requires': install_reqs,
'test_requires': test_reqs,
'extras_require': reqs,
...
)
SO 질문에 대한 답변을 크로스 투고하여 심플하고 pip 버전 증명 솔루션을 제공합니다.
try: # for pip >= 10
from pip._internal.req import parse_requirements
from pip._internal.download import PipSession
except ImportError: # for pip <= 9.0.3
from pip.req import parse_requirements
from pip.download import PipSession
requirements = parse_requirements(os.path.join(os.path.dirname(__file__), 'requirements.txt'), session=PipSession())
if __name__ == '__main__':
setup(
...
install_requires=[str(requirement.req) for requirement in requirements],
...
)
나서, 필요한 .requirements.txt
프로젝트 루트 디렉터리에 있습니다.
다른 또나하parse_requirements
를 환경지 into로 extras_require
:
from collections import defaultdict
from pip.req import parse_requirements
requirements = []
extras = defaultdict(list)
for r in parse_requirements('requirements.txt', session='hack'):
if r.markers:
extras[':' + str(r.markers)].append(str(r.req))
else:
requirements.append(str(r.req))
setup(
...,
install_requires=requirements,
extras_require=extras
)
sdist와 binary dist를 모두 지원합니다.
, 田른 as as as as as as as as as as as as as as as as as.parse_requirements
에는 몇 가지 단점이 있기 때문에 공공 프로젝트에서는 이 방법을 사용할 수 없지만 내부/개인 프로젝트에서는 충분할 수 있습니다.
나는 이렇게 했다:
import re
def requirements(filename):
with open(filename) as f:
ll = f.read().splitlines()
d = {}
for l in ll:
k, v = re.split(r'==|>=', l)
d[k] = v
return d
def packageInfo():
try:
from pip._internal.operations import freeze
except ImportError:
from pip.operations import freeze
d = {}
for kv in freeze.freeze():
k, v = re.split(r'==|>=', kv)
d[k] = v
return d
req = getpackver('requirements.txt')
pkginfo = packageInfo()
for k, v in req.items():
print(f'{k:<16}: {v:<6} -> {pkginfo[k]}')
.pip 9.0.1
)는, Romain의 대답에 근거하고 있습니다.requirements.txt
현재 환경 마커에 따라 필터링합니다.
from pip.req import parse_requirements
requirements = []
for r in parse_requirements('requirements.txt', session='hack'):
# check markers, such as
#
# rope_py3k ; python_version >= '3.0'
#
if r.match_markers():
requirements.append(str(r.req))
print(requirements)
언급URL : https://stackoverflow.com/questions/14399534/reference-requirements-txt-for-the-install-requires-kwarg-in-setuptools-setup-py
'itsource' 카테고리의 다른 글
JavaScript: 위치.새 창/탭에서 여는 href를 선택하십시오. (0) | 2022.11.14 |
---|---|
@ComponentScan 주석을 사용하여 여러 경로를 스캔하려면 어떻게 해야 합니까? (0) | 2022.11.14 |
MySQL에서 날짜/시간에서 시간을 빼는 방법 (0) | 2022.11.14 |
PHP에서 시간대를 지정하여 현재 날짜를 가져오시겠습니까? (0) | 2022.11.14 |
Larabel 5 – URL에서 공개 삭제 (0) | 2022.11.14 |