如何编写代码片段#
用户通过示例学习。因此,无论您是在编写文档字符串还是用户指南,都应包含说明相关API的示例。您的示例应开箱即用,以便用户可以复制它们并根据自身需求进行调整。
本页描述如何编写代码片段,以便在CI中进行测试。
备注
本指南中的示例使用 reStructuredText。如果您正在编写 Markdown,请使用 MyST 语法。要了解更多信息,请阅读 MyST 文档。
示例类型#
有三种类型的示例:doctest-style、code-output-style 和 literalinclude。
doctest-style 示例#
doctest-style 示例模仿了交互式 Python 会话。
.. doctest::
>>> def is_even(x):
... return (x % 2) == 0
>>> is_even(0)
True
>>> is_even(1)
False
它们是这样渲染的:
>>> def is_even(x):
... return (x % 2) == 0
>>> is_even(0)
True
>>> is_even(1)
False
小技巧
如果你在编写文档字符串,请排除 .. doctest::
以简化你的代码。
Example:
>>> def is_even(x):
... return (x % 2) == 0
>>> is_even(0)
True
>>> is_even(1)
False
code-output-style 示例#
code-output-style 示例包含普通的 Python 代码。
.. testcode::
def is_even(x):
return (x % 2) == 0
print(is_even(0))
print(is_even(1))
.. testoutput::
True
False
它们是这样渲染的:
def is_even(x):
return (x % 2) == 0
print(is_even(0))
print(is_even(1))
True
False
literalinclude 示例#
literalinclude 示例显示 Python 模块。
.. literalinclude:: ./doc_code/example_module.py
:language: python
:start-after: __is_even_begin__
:end-before: __is_even_end__
# example_module.py
# fmt: off
# __is_even_begin__
def is_even(x):
return (x % 2) == 0
# __is_even_end__
# fmt: on
它们是这样渲染的:
def is_even(x):
return (x % 2) == 0
你应该写哪种类型的示例?#
关于应该使用哪种风格没有硬性规定。选择最能说明你的API的风格。
小技巧
如果你不确定使用哪种样式,请使用 code-block-style。
何时使用 doctest-style#
如果你正在编写一个小示例来强调对象表示,或者如果你想打印中间对象,请使用 doctest-style。:
.. doctest::
>>> import ray
>>> ds = ray.data.range(100)
>>> ds.schema()
Column Type
------ ----
id int64
>>> ds.take(5)
[{'id': 0}, {'id': 1}, {'id': 2}, {'id': 3}, {'id': 4}]
何时使用 代码块样式#
如果你正在写一个较长的示例,或者对象表示与你的示例无关,请使用 code-block-style。:
.. testcode::
from typing import Dict
import numpy as np
import ray
ds = ray.data.read_csv("s3://anonymous@air-example-data/iris.csv")
# Compute a "petal area" attribute.
def transform_batch(batch: Dict[str, np.ndarray]) -> Dict[str, np.ndarray]:
vec_a = batch["petal length (cm)"]
vec_b = batch["petal width (cm)"]
batch["petal area (cm^2)"] = vec_a * vec_b
return batch
transformed_ds = ds.map_batches(transform_batch)
print(transformed_ds.materialize())
.. testoutput::
MaterializedDataset(
num_blocks=...,
num_rows=150,
schema={
sepal length (cm): double,
sepal width (cm): double,
petal length (cm): double,
petal width (cm): double,
target: int64,
petal area (cm^2): double
}
)
何时使用 literalinclude#
如果你在编写端到端示例,并且你的示例不包含输出,请使用 literalinclude。
如何处理难以测试的示例#
什么时候可以不测试一个示例?#
你不需要测试那些依赖于外部系统(如Weights and Biases)的示例。
跳过 doctest-style 示例#
要跳过一个 doctest-style 示例,请在您的 Python 代码后附加 # doctest: +SKIP
。
.. doctest::
>>> import ray
>>> ray.data.read_images("s3://private-bucket") # doctest: +SKIP
跳过 代码块样式 示例#
要跳过一个 代码块样式 的示例,请在 testoutput
块中添加 :skipif: True
。
.. testcode::
:skipif: True
from ray.air.integrations.wandb import WandbLoggerCallback
callback = WandbLoggerCallback(
project="Optimization_Project",
api_key_file=...,
log_config=True
)
如何处理长或不确定的输出#
如果你的 Python 代码是非确定性的,或者如果你的输出过长,你可能想要跳过全部或部分输出。
忽略 doctest-style 输出#
要忽略 doctest-style 输出的一部分,请将问题部分替换为省略号。:
>>> import ray
>>> ray.data.read_images("s3://anonymous@ray-example-data/image-datasets/simple")
Dataset(
num_rows=...,
schema={image: numpy.ndarray(shape=(32, 32, 3), dtype=uint8)}
)
要完全忽略一个输出,写一个 代码块风格 的片段。不要使用 # doctest: +SKIP
。
忽略 代码块样式 输出#
如果你的输出部分较长或不确定,请用省略号替换有问题的部分。
.. testcode::
import ray
ds = ray.data.read_images("s3://anonymous@ray-example-data/image-datasets/simple")
print(ds)
.. testoutput::
Dataset(
num_rows=...,
schema={image: numpy.ndarray(shape=(32, 32, 3), dtype=uint8)}
)
如果你的输出是不确定的,并且你想显示一个示例输出,请添加 :options: +MOCK
。
.. testcode::
import random
print(random.random())
.. testoutput::
:options: +MOCK
0.969461416250246
如果你的输出难以测试,并且你不想显示示例输出,请排除 testoutput
。
.. testcode::
print("This output is hidden and untested")
如何使用GPU测试示例#
要配置 Bazel 以在 GPU 上运行示例,请完成以下步骤:
打开相应的
BUILD
文件。如果你的示例在doc/
文件夹中,打开doc/BUILD
。如果你的示例在python/
文件夹中,打开类似python/ray/train/BUILD
的文件。找到
doctest
规则。它看起来像这样:doctest( files = glob( include=["source/**/*.rst"], ), size = "large", tags = ["team:none"] )
将包含示例的文件添加到排除文件列表中。
doctest( files = glob( include=["source/**/*.rst"], exclude=["source/data/requires-gpus.rst"] ), tags = ["team:none"] )
如果尚不存在,创建一个
doctest
规则,并将gpu
设置为True
。doctest( files = [], tags = ["team:none"], gpu = True )
将包含示例的文件添加到GPU规则中。:
doctest( files = ["source/data/requires-gpus.rst"] size = "large", tags = ["team:none"], gpu = True )
有关实际示例,请参见 doc/BUILD
或 python/ray/train/BUILD
。
如何在本地测试示例#
要在本地测试示例,请安装 pytest-sphinx
的 Ray 分支。
pip install git+https://github.com/ray-project/pytest-sphinx
然后,在模块、文档字符串或用户指南上运行 pytest。
pytest --doctest-modules python/ray/data/read_api.py
pytest --doctest-modules python/ray/data/read_api.py::ray.data.read_api.range
pytest --doctest-modules doc/source/data/getting-started.rst