英文 | Configuration & API

出处 | nox 官方文档

译者 | 豌豆花下猫@Python猫

Github地址:https://github.com/chinesehuazhou/nox_doc_cn

声明:本翻译基于CC BY-NC-SA 4.0授权协议,内容略有改动,转载请保留原文出处,请勿用于商业或非法用途。

接上篇《更好用的 Python 任务自动化工具:nox 官方教程

Noxfile

Nox 默认在一个名为noxfile.py的文件中查找配置。在运行 nox 时,你可以使用 --noxfile参数指定其它的文件。

定义会话

格式:session(func=None, python=None, py=None, reuse_venv=None, name=None, venv_backend=None),将被装饰的函数指定为一个会话。

Nox 会话是通过被@nox.session装饰的标准 Python 函数来配置的。例如:

import nox

@nox.session
def tests(session):
session.run('pytest')

会话描述

你可以使用文档字符串向会话中添加一个描述。第一行内容会在列出会话时显示。例如:

import nox

@nox.session
def tests(session):
"""Run the test suite."""
session.run('pytest')

nox --list命令将显示出:

$ nox --list
Available sessions:
* tests -> Run the test suite.

会话名称

默认情况下,Nox 使用被装饰函数的名称作为会话的名称。这对于绝大多数项目都非常有效,但是,如果需要,你也可以使用 @nox.session 的 name 参数来自定义会话的名称。例如:

import nox

@nox.session(name="custom-name")
def a_very_long_function_name(session):
print("Hello!")

nox --list 命令将显示:

$ nox --list
Available sessions:
* custom-name

你可以告诉 nox 使用自定义的名称运行会话:

$ nox --session "custom-name"
Hello!

配置会话的virtualenv

默认情况下,Nox 在为每个会话创建一个新的 virtualenv 时,会使用 Nox 所用的同一个解释器。如果你使用 Python 3.6 安装了 nox,则 nox 将默认在所有会话中使用 Python 3.6。

通过给 @nox.session 指定 python 参数(或其别名 py),你可以告诉 nox 使用不同的 Python 解释器/版本:

@nox.session(python='2.7')
def tests(session):
pass

你还可以告诉 Nox 使用多个 Python 解释器运行你的会话。Nox 将为指定的每个解释器创建一个单独的 virtualenv 并运行会话。例如,下面的会话将运行两次——一次使用 Python 2.7,一次使用 Python 3.6:

@nox.session(python=['2.7', '3.6'])
def tests(session):
pass

当你提供一个版本号时,Nox 会自动添加 python 来确定可执行文件的名称。但是,Nox 也可以接受完整的可执行名称。如果你想使用 pypy 来测试,例如:

@nox.session(python=['2.7', '3.6', 'pypy-6.0'])
def tests(session):
pass

当准备你的会话时,Nox 将为每个解释器创建单独的会话。你可以在运行 nox --list 的时候看到这些会话。例如这个 Noxfile:

@nox.session(python=['2.7', '3.5', '3.6', '3.7'])
def tests(session):
pass

将产生这些会话:

* tests-2.7
* tests-3.5
* tests-3.6
* tests-3.7

注意,这个扩展发生在参数化之前,所以你仍然可以对多个解释器的会话进行参数化。

如果你想完全禁止创建 virtualenv,你可以设置 python 参数为 False:

@nox.session(python=False)
def tests(session):
pass

最后,你还可以指定每次都重用 virtualenv,而不是重新创建:

@nox.session(
python=['2.7', '3.6'],
reuse_venv=True)
def tests(session):
pass

将参数传入会话

通常往测试会话中传递参数是很有用的。下面是一个简单示例,演示了如何使用参数对特定文件作测试:

@nox.session
def test(session):
session.install('pytest') if session.posargs:
test_files = session.posargs
else:
test_files = ['test_a.py', 'test_b.py'] session.run('pytest', *test_files)

现在如果你运行:

nox

那么 nox 将运行:

pytest test_a.py test_b.py

但如果你运行:

nox -- test_c.py

那么 nox 将运行:

pytest test_c.py

参数化会话

会话的参数可以用nox.parametrize() 装饰器来作参数化。下面是一个典型的参数化安装 Django 版本的例子:

@nox.session
@nox.parametrize('django', ['1.9', '2.0'])
def tests(session, django):
session.install(f'django=={django}')
session.run('pytest')

当你运行nox时,它会创建两个不同的会话:

$ nox
nox > Running session tests(django='1.9')
nox > pip install django==1.9
...
nox > Running session tests(djano='2.0')
nox > pip install django==2.0

nox.parametrize() 的接口和用法故意跟pytest的参数化 相类似。

格式:parametrize(arg_names, arg_values_list, ids=None)

作用是参数化一个会话。

将 arg_values_list 列表赋给对应的 arg_names,为装饰的会话函数添加新的调用。参数化在会话发现期间执行,每次调用都作为 nox 的单个会话出现。

参数:

  • arg_names (Sequence[str])——一系列参数名称
  • arg_values_list (Sequence[Union[Any, Tuple]])——参数值列表决定了使用不同参数值调用会话的频率。如果只指定了一个参数名,那么这就是一个简单的值列表,例如[1,2,3]。如果指定了 N 个参数名,这必须是一个 N 元组的列表,其中每个元素为其各自的参数名指定一个值,例如 [(1,'a'), (2,'b')]。
  • ids (Sequence[str]) ——可选项,一系列测试 id,被参数化的参数使用。

你也可以堆叠装饰器,令其产生组合了参数的会话,例如:

@nox.session
@nox.parametrize('django', ['1.9', '2.0'])
@nox.parametrize('database', ['postgres', 'mysql'])
def tests(session, django, database):
...

如果运行nox —list,你将看到它生成了以下的会话集:

* tests(database='postgres', django='1.9')
* tests(database='mysql', django='1.9')
* tests(database='postgres', django='2.0')
* tests(database='mysql', django='2.0')

如果你只想运行一个参数化会话,请参阅"指定参数化会话"部分。

为参数化的会话起友好的名称

自动生成的参数化会话的名称,如tests(django='1.9', database='postgres'),即使用关键字过滤,也可能很长且很难处理。

在此场景中,可以为参数化会话提供辅助的自定义 id 。这两个例子是等价的:

@nox.session
@nox.parametrize('django',
['1.9', '2.0'],
ids=['old', 'new'])
def tests(session, django):
...
@nox.session
@nox.parametrize('django', [
nox.param('1.9', id='old'),
nox.param('2.0', id='new'),
])
def tests(session, django):
...

当运行nox --list时,你将看到它们的新 id:

* tests(old)
* tests(new)

你可以用nox --sessions "tests(old)",以此类推。

这也适用于堆叠参数化。id 是在组合期间组合的。例如:

@nox.session
@nox.parametrize(
'django',
['1.9', '2.0'],
ids=["old", "new"])
@nox.parametrize(
'database',
['postgres', 'mysql'],
ids=["psql", "mysql"])
def tests(session, django, database):
...

运行nox --list时会产生这些会话:

* tests(psql, old)
* tests(mysql, old)
* tests(psql, new)
* tests(mysql, new)

会话对象

Nox 将使用 Session 类的一个实例来调用你的会话函数。

class Session(runner)

会话对象被传递到用户自定义的每个会话函数中。

这是在 Nox 会话中安装软件包和运行命令的主要途径。

  • bin——virtualenv 的 bin 目录

  • cd(dir)——chdir() 的一个别名

  • chdir(dir)——更改当前的工作目录

  • conda_install(*args, **kwargs)

    调用conda install来在会话环境中的安装软件包。

    直接安装软件包:

    session.conda_install('pandas')
    session.conda_install('numpy', 'scipy')
    session.conda_install('--channel=conda-forge', 'dask==2.1.0')

    根据 requirements.txt 文件来安装软件包:

    session.conda_install('--file', 'requirements.txt')
    session.conda_install('--file', 'requirements-dev.txt')

    不破坏 conda 已安装的依赖而安装软件包:

    session.install('.', '--no-deps')
    # Install in editable mode.
    session.install('-e', '.', '--no-deps')

    剩下的关键字参数跟 run() 相同。

  • env——一个环境变量的字典,传给所有的命令。

  • error(*args, **kwargs)——立即中止会话并随意地记录一个错误。

  • install(*args, **kwargs) ——调用 pip 在会话的 virtualenv 里安装包。

    直接安装包:

    session.install('pytest')
    session.install('requests', 'mock')
    session.install('requests[security]==2.9.1')

    根据 requirements.txt 文件来安装软件包:

    session.install('-r', 'requirements.txt')
    session.install('-r', 'requirements-dev.txt')

    安装当前的包:

    session.install('.')
    # Install in editable mode.
    session.install('-e', '.')

    剩下的关键字参数跟 run() 相同。

  • interactive ——如果 Nox 在交互式会话中运行,则返回 True,否则返回 False。

  • log(*args, **kwargs)——在会话期间输出一份日志。

  • notify(target) ——将给定的会话放在队列的末尾。

    此方法是幂等的;对同一会话的多次通知无效。

    参数:target (Union[str, Callable])——需要通知的会话。这可以指定适当的字符串(与nox -s 的使用相同)或使用函数对象。

  • posargs ——用于设置从命令行上传给 nox 的额外参数。

  • python ——传给@nox.session的 Python 版本。

  • run(args, env=None, kwargs) ——运行一个命令。

    命令必须安装字符串列表指定,例如:

    session.run('pytest', '-k', 'fast', 'tests/')
    session.run('flake8', '--import-order-style=google')

    你不能把所有东西都当作一个字符串传递。例如,不可以这样:

    session.run('pytest -k fast tests/')

    你可以用env 为命令设置环境变量:

    session.run(
    'bash', '-c', 'echo $SOME_ENV',
    env={'SOME_ENV': 'Hello'})

    你还可以使用success_codes ,告诉 nox 将非零退出码视为成功。例如,如果你想将 pytest 的“tests discovered, but none selected”错误视为成功:

    session.run(
    'pytest', '-k', 'not slow',
    success_codes=[0, 5])

    在 Windows 上,像del这样的内置命令不能直接调用,但是你可以使用cmd /c 来调用它们:

    session.run('cmd', '/c', 'del', 'docs/modules.rst')

    参数:

    • env (dict or None)——用于向命令公开的环境变量字典。默认情况下,传递所有环境变量。
    • silent (bool) ——静默命令输出,除非命令失败。默认为 False。
    • success_codes (list, tuple, or None)——一系列被认为是成功的返回码。默认情况下,只有 0 被认为是成功的。
    • external (bool) ——如果为 False(默认值),那么不在 virtualenv 路径中的程序将发出告警。如果为 True,则不会发出告警。这些告警可以使用--error-on-external-run将其转换为错误。这对没有 virtualenv 的会话没有影响。
  • skip(*args, **kwargs) ——立即跳出会话,并随意记录一个告警。

  • virtualenv ——运行所有命令的 virtualenv。

修改 Noxfile 中的 Nox 行为

Nox 有各种命令行参数,可用于修改其行为。其中一些还可以在 Noxfile 中使用 nox.options 指定。例如,如果你想将 Nox 的 virtualenvs 存储在不同的目录中,而不需要每次都将它传递给 nox:

import nox

nox.options.envdir = ".cache"

@nox.session
def tests(session):
...

或者,如果你想提供一组默认运行的会话:

import nox

nox.options.sessions = ["lint", "tests-3.6"]

...

以下的选项可以在 Noxfile 中指定:

  • nox.options.envdir 等同于指定 –envdir.
  • nox.options.sessions 等同于指定 -s or –sessions.
  • nox.options.keywords 等同于指定 -k or –keywords.
  • nox.options.reuse_existing_virtualenvs 等同于指定 –reuse-existing-virtualenvs 。通过在调用时指定 --no-reuse-existing-virtualenvs ,你可以强制取消它。
  • nox.options.stop_on_first_error 等同于指定 –stop-on-first-error. 通过在调用时指定 --no-stop-on-first-error,你可以强制取消它。
  • nox.options.error_on_missing_interpreters 等同于指定 –error-on-missing-interpreters 。通过在调用时指定 --no-error-on-missing-interpreters ,你可以强制取消它。
  • nox.options.error_on_external_run 等同于指定 –error-on-external-run. 通过在调用时指定 --no-error-on-external-run ,你可以强制取消它。
  • nox.options.report 等同于指定 –report

在调用 nox 时,命令行上指定的任何选项都优先于 Noxfile 中指定的选项。如果在命令行上指定了--sessions--keywords,那么在 Noxfile 中指定的两个选项都将被忽略。

公众号【Python猫】, 本号连载优质的系列文章,有喵星哲学猫系列、Python进阶系列、好书推荐系列、技术写作、优质英文推荐与翻译等等,欢迎关注哦。

Python 任务自动化工具:nox 的配置与 API的更多相关文章

  1. 更好用的 Python 任务自动化工具:nox 官方教程

    英文| nox tutorial 出处| nox 官方文档 译者| 豌豆花下猫@Python猫 Github地址:https://github.com/chinesehuazhou/nox_doc_c ...

  2. Python 任务自动化工具 tox 教程

    在我刚翻译完的 Python 打包系列文章中,作者提到了一个神奇的测试工具 tox,而且他本人就是 tox 的维护者之一.趁着话题的相关性,本文将对它做简单的介绍,说不定大家在开发项目时能够用得上. ...

  3. 强大的 Python 任务自动化工具!invoke 十分钟入门指南

    接着前面的<tox 教程>,以及刚翻译好的<nox文档>,我们继续聊聊 Python 任务自动化的话题. nox 的作者在去年的 Pycon US 上,做了一场题为<Br ...

  4. python 包管理工具 pip 的配置

    近几年来,python的包管理系统pip 越来越完善, 尤其是对于 windows场景下,pip大大改善了python的易用性. https://www.cnblogs.com/yvivid/p/pi ...

  5. 阿里最强 Python 自动化工具开源了!

    1. 前言 大家好,我是安果! 最近,阿里内部开源了一个 iOS 端由 Python 编写的自动化工具,即:tidevice 它是一款跨平台的自动化开源工具,不依赖 Xcode 就可以启动 WebDr ...

  6. 学习安装并配置前端自动化工具Gulp

    Gulp和所有Gulp插件都是基于nodeJs来运行的,因此在你的电脑上需要安装nodeJs,安装过程请移驾安装并配置前端自动化工具--grunt.安装完成后,通过运行cmd进入DOS命令窗口,如图: ...

  7. 简单的抓取淘宝关键字信息、图片的Python爬虫|Python3中级玩家:淘宝天猫商品搜索爬虫自动化工具(第一篇)

    Python3中级玩家:淘宝天猫商品搜索爬虫自动化工具(第一篇) 淘宝改字段,Bugfix,查看https://github.com/hunterhug/taobaoscrapy.git 由于Gith ...

  8. Ansible :一个配置管理和IT自动化工具

    编译文章:LCTT  https://linux.cn/article-4215-1.html 译者: felixonmars 文章地址:https://linux.cn/article-4215-1 ...

  9. 开源自己用python封装的一个Windows GUI(UI Automation)自动化工具,支持MFC,Windows Forms,WPF,Metro,Qt

    首先,大家可以看下这个链接 Windows GUI自动化测试技术的比较和展望 . 这篇文章介绍了Windows中GUI自动化的三种技术:Windows API, MSAA - Microsoft Ac ...

随机推荐

  1. 【TensorFlow】理解tf.nn.conv2d方法 ( 附代码详解注释 )

    最近在研究学习TensorFlow,在做识别手写数字的demo时,遇到了tf.nn.conv2d这个方法,查阅了官网的API 发现讲得比较简略,还是没理解.google了一下,参考了网上一些朋友写得博 ...

  2. 洛谷P1809 过河问题 经典贪心问题

    作者:zifeiy 标签:贪心 题目链接:https://www.luogu.org/problem/P1809 我们假设第 \(i\) 个人过河的耗时是 \(t[i]\) ,并且 \(t[i]\) ...

  3. 2018-8-10-C#-代码占用的空间

    title author date CreateTime categories C# 代码占用的空间 lindexi 2018-08-10 19:16:52 +0800 2018-2-13 17:23 ...

  4. 如何读取redis中的key值中的结果

    redis的值有5种类型,不同的类型有不同的命令来获取: 字符直接 get key 队列 左端弹出一个元素  LPOP key 哈希 HGET key field 集合 SMEMBERS key 返回 ...

  5. linux平台依赖性

    每个电脑平台有其自己的特点, 内核设计者可以自由使用所有的特性来获得更好的性能. in the target object file ??? 不象应用程序开发者, 他们必须和预编译的库一起连接他们的代 ...

  6. CSU 2005: Nearest Maintenance Point(Dijkstra + bitset)

    Description A county consists of n cities (labeled 1, 2, …, n) connected by some bidirectional roads ...

  7. H3C 802.1X基本配置

  8. python写的有声小说爬虫

    querybook.py from bs4 import BeautifulSoup from lxml import html import xml import requests import s ...

  9. 【35.86%】【POJ 1962】Corporative Network

    Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 3943 Accepted: 1414 Description A very bi ...

  10. Python6_模块、包、import、from import的解释

    先说一下模块和包是什么? 模块(module):简单来说一个模块(module)就是一个py文件.在python中是这么约定. 模块里面有函数.类,就是一组代码的集合.   模块显然要有一个名字,这个 ...