我有一個知識分歧,我很感謝幫助。以下前兩節給出了一些序言;第三個包含問題。我很樂意回答我的原始問題和有關如何更好/更清潔等問題的建議。用一個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 - 友好測試)
不幸的是,這個電抗器:兩個py27
和py36
,TOX嘗試安裝所有的軟件包(DEV和「正規」)從我的Pipfile
;當py27
試圖安裝aiohttp時,顯然會窒息。
所以,問題是:我該如何充分(和Python)測試這兩個版本的Python與這個邏輯和結構?