2017-07-14 65 views
-1

我有一个知识分歧,我很感谢帮助。以下前两节给出了一些序言;第三个包含问题。我很乐意回答我的原始问题有关如何更好/更清洁等问题的建议。用一个3.x特性测试一个2.7友好的Python包

的设置

我已经开发了在起始于2.7的Python的所有版本以及基于HTTP的库(使用Requests)。最近有人要求该库支持通过aiohttp的异步HTTP请求,正如你毫无疑问知道的那样,这个库需要Python> = 3.4.2。

我只需要翻出请求并将其替换为aiohttp,但我的用户群中有一小部分用户需要在Python 2.x中工作。所以,我决定在适当的设置中使用这两个库。

设想一个Client对象做所有HTTP交易:

import mylib 

client = mylib.Client() 
data = client.get() 
client.update_setting(<setting_id>) 
# etc. 

考虑之后,我觉得我想要做这样的事情:

client = mylib.Client(asynchronous=True) 

...在这一点Client的方法现在将使用异步,aiottp驱动的变体。如果用户试图在Python < 3.4.2上以这种方式实例化Client,则会记录一条警告,并且该库会回退到使用同步Client

出版

我已经配置了我的setup.py来处理这个问题:Python版本> = 3.4.2将安装aiohttp(及其相关项),而版本3.4.2 <不会:

import sys 

import setuptools 

BASE_ASYNC_PYTHON_VER = int(hex(0x030402f0), 16) 
PACKAGES = ['mylib'] 
REQUIRED = ['requests'] 
EXTRAS = {} 

# Handles environments with old versions of setuptools: 
if int(setuptools.__version__.split(".", 1)[0]) < 18: 
    if sys.hexversion < BASE_ASYNC_PYTHON_VER: 
     REQUIRED.append('aiodns') 
     REQUIRED.append('aiohttp') 
     REQUIRED.append('cchardet') 
    else: 
     EXTRAS[":python_version>='3.4.2'"] = ['aiodns', 'aiohttp', 'cchardet'] 

# Removing extraneous stuff for this example: 
setuptools.setup(
    name='mylib', 
    version='1.0.0' 
    description='Just for grims', 
    packages=PACKAGES, 
    install_requires=REQUIRED, 
    extras_require=EXTRAS, 

这个效果非常好:Python 2安装避开了那些额外的库,Python 3安装包含了它们。

问题带有...

测试

我用pipenv来管理我的依赖,并同时开发的virtualenv。我Pipfile看起来是这样的:

[[source]] 
url = "https://pypi.python.org/simple" 
verify_ssl = true 

[dev-packages] 
detox = "*" 
pytest = "*" 
requests-mock = "*" 
tox = "*" 
twine = "*" 

[packages] 
aiodns = "*" 
aiohttp = "*" 
cchardet = "*" 
requests = "*" 

注意,似乎没有成为一个方式说,“只有安装包版本的Python X.Y.Z。”

我也使用tox跨多个Python版本运行我的测试;我tox.ini看起来是这样的:

[tox] 
envlist = py27, py36 

[testenv] 
passenv=HOME 
deps = pipenv 
commands= 
    pipenv install --dev 
    pipenv run py.test tests 

(其中tests包含一组pytest - 友好测试)

不幸的是,这个电抗器:两个py27py36,TOX尝试安装所有的软件包(DEV和“正规”)从我的Pipfile;当py27试图安装aiohttp时,显然会窒息。

所以,问题是:我该如何充分(和Python)测试这两个版本的Python与这个逻辑和结构?

回答

0

我做了一些调查,但没有得到完整的答案 - 留下我在搜索时发现的有用信息。

pipfile应该可能支持dependency markers。有在pipfile了“让我们使用toml”问题an example,它看起来是这样的:

# environment markers 
SomeProject2 = {version = "==5.4", markers = {python_version = "< 2.7", sys_platform = "win32"}} 

在试图获得这与toml,pipfile,pipenv我遇到了以下问题的最新版本中运行蟒蛇实施toml解析器:https://github.com/uiri/toml/issues/118

在另一方面,你一般不应使用分支逻辑在setup.py选择的依赖,因为这些会得到出炉到您的包构建的轮子。我有written up slides为什么这是一个问题,如果你想了解更多的信息。 tl;dr如何使这项工作优雅地再次与环境说明符:

setup(
    ... 
    extras_require={ 
     ':python_version=="2.7"': ['functools32'], 
    }, 
)