2017-07-14 66 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'], 
    }, 
)