1
1
# Python 文档示例代码书写规范
2
2
3
+ ## 书写规范
4
+
3
5
规范概要:
4
6
5
7
1 . 第 1 节,显式的输出优于注释
10
12
执行说明:
11
13
12
14
1 . 规范在执行过程中,可能会发现现有规范未考虑到的方面,需要在实施过程中不断补充与完善,也请大家积极反馈意见。
13
- 2 . 示例代码的执行限时为 ` 10 ` 秒,即,要求示例代码在 ` 10 ` 秒内执行完毕。如有特殊情况,如网络下载等情况,可以向 reviewer 提出增加 ` TIMEOUT ` 选项 。
15
+ 2 . 示例代码的执行限时为 ` 10 ` 秒,即,要求示例代码在 ` 10 ` 秒内执行完毕。如有特殊情况,如网络下载等情况,可以向 reviewer 提出增加 ` TIMEOUT ` 指令 。
14
16
3 . 如遇其他问题,如符合规范的示例代码无法进行检查等情况,请及时反馈 reviewer 进行确认。
15
17
16
- ## 1. 显式的输出优于注释
18
+ ### 显式的输出优于注释
17
19
18
20
请尽量将用户可能关注的输出,如变量的值、` Tensor ` 的 ` shape ` 等,书写或拷贝至示例中。
19
21
@@ -181,7 +183,7 @@ Tensor(shape=[2, 2], dtype=int64, place=Place(cpu), stop_gradient=True,
181
183
99
182
184
```
183
185
184
- # # 2. 固定的输出优于随机
186
+ # ## 固定的输出优于随机
185
187
186
188
请尽量保证输出为固定值,对于示例中的随机情况,请设置随机种子。
187
189
@@ -199,7 +201,7 @@ Tensor(shape=[2, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
199
201
200
202
如果示例中涉及 ` Python ` 、` Numpy ` 随机数等情况,也需要进行随机种子的设置。
201
203
202
- ## 3. 明确的设备优于默认
204
+ ### 明确的设备优于默认
203
205
204
206
由于 ` Tensor ` 在 ` CPU ` 、` GPU ` 等设备上面的行为可能不同,请写明具体的设备需求。
205
207
@@ -250,7 +252,7 @@ CI 中默认使用 `CPU` 作为检查环境,因此,如无特殊情况,可
250
252
251
253
请注意这里的 **大小写** ,其中 `doctest` 为小写,`REQUIRES` 为大写,`env` 为小写,`GPU` 为大写。
252
254
253
- ## 4. 尝试去检查优于跳过
255
+ ### 尝试去检查优于跳过
254
256
255
257
示例代码的检查可以保证其正确性,但并不是所有代码均能够正常或正确的在 CI 环境中运行。
256
258
@@ -283,17 +285,29 @@ CI 中默认使用 `CPU` 作为检查环境,因此,如无特殊情况,可
283
285
- ` +SKIP ` 表示后面的代码要跳过,` -SKIP ` 表示恢复检查。
284
286
- ` +SKIP ` 可以加上说明,如 ` +SKIP('file not exist') `
285
287
288
+ ## 特殊指令
289
+
290
+ ### TIMEOUT 指令
291
+
292
+ #### 指令格式
293
+
294
+ ``` text
295
+ directive ::= "# doctest: +TIMEOUT(" time ")"
296
+ time ::= nonzerodigit (digit)*
297
+ nonzerodigit ::= "1"..."9"
298
+ digit ::= "0"..."9"
299
+ ```
286
300
287
- ## TIMEOUT 选项
301
+ #### 指令说明
288
302
289
- 示例代码检查的默认限制时间为 ` 10 ` 秒,但有些情况下代码无法及时完成运行,如,需要通过网络下载较大的模型或数据集。如果出现此类情况,开发者可以与 reviewer 协商增加 ` TIMEOUT ` 选项 ,如:
303
+ 示例代码检查的默认限制时间为 ` 10 ` 秒,但有些情况下代码无法及时完成运行,如,需要通过网络下载较大的模型或数据集。如果出现此类情况,开发者可以与 reviewer 协商增加 ` TIMEOUT ` 指令 ,如:
290
304
291
305
``` python
292
306
>> > from paddle.vision.datasets import VOC2012
293
307
>> > voc2012 = VOC2012()
294
308
```
295
309
296
- 此段示例代码需要通过网络进行下载,运行时间超过了限制的执行时间 ` 10 ` 秒,此时,在 reviewer 同意的情况下,可以添加 ` TIMEOUT ` 选项 ,修改为:
310
+ 此段示例代码需要通过网络进行下载,运行时间超过了限制的执行时间 ` 10 ` 秒,此时,在 reviewer 同意的情况下,可以添加 ` TIMEOUT ` 指令 ,修改为:
297
311
298
312
``` text
299
313
>>> # doctest: +TIMEOUT(60)
@@ -306,7 +320,67 @@ CI 中默认使用 `CPU` 作为检查环境,因此,如无特殊情况,可
306
320
` TIMEOUT ` 的具体时长可根据实际情况进行修改。
307
321
308
322
309
- ## 参考资料:
323
+ ### SOLO 指令
324
+
325
+ #### 指令格式
326
+
327
+ ``` text
328
+ directive ::= "# doctest: +SOLO(" reason ")"
329
+ reason ::= "'" shortstringchar+ "'" | '"' shortstringchar+ '"'
330
+ shortstringchar ::= <any source character except "\" or newline or the quote>
331
+ ```
332
+
333
+ #### 指令说明
334
+
335
+ ` SOLO ` 多指音乐中的 ` 独奏 ` ,在示例代码的写作中,用以指代 ` Main Process Separately ` ,即,指示示例检查工具使用 ` 主进程单独 ` 运行此示例代码。
336
+
337
+ 示例检查工具使用了 ` python ` 中的 ` multiprocessing ` 模块,虽然 ` multiprocessing ` 多应用于多进程加速,但,在示例检查中,主要用作隔离各个示例代码的检查环境,这有几个原因:
338
+
339
+ - ` Paddle ` 是一个庞大且复杂的框架,涉及较多全局变量,以及动态图与静态图转换等操作,客观上要求每次示例代码的运行保持干净的初始化状态
340
+ - 示例代码检查与单元测试不同,一般不会进行复杂的运行前后处理(如 ` setUp ` 、` tearDown ` ),这就导致了单个示例运行之后,可能污染检查环境
341
+ - ` Paddle ` 内部的一些接口,如异步 ` io ` 等操作,也会涉及到多进程操作,这就要求示例检查工具不能够影响 ` Paddle ` 自身的进程管理
342
+
343
+ 基于此,示例检查工具遵循以下设计:
344
+
345
+ - 示例检查工具在每次运行检查前,都会单独创建进程,并在进程中 ` import paddle ` ,以初始化环境
346
+ - 示例检查工具使用 ` python ` 的 ` multiprocessing ` 开辟进程,基于安全性的考虑([ Contexts and start methods] ( https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods ) ),使用 ` spawn ` 的方式
347
+ - 由于多进程嵌套可能存在问题,如示例中使用异步 ` io ` 又开辟多个进程,特此引入 ` SOLO ` 指令,指示示例检查工具,此示例代码需要在主进程中单独运行
348
+
349
+ 以一个简单的多进程代码为例:
350
+
351
+ ``` python
352
+
353
+ >> > import multiprocessing
354
+ >> > p = multiprocessing.Process(
355
+ ... target = lambda a , b : a + b,
356
+ ... args = (1 , 2 ),
357
+ ... )
358
+ >> > p.start()
359
+ >> > p.join()
360
+
361
+ ```
362
+
363
+ 在 reviewer 同意的情况下,可以添加 ` SOLO ` 指令,修改为:
364
+
365
+ ``` text
366
+
367
+ >>> # doctest: +SOLO('can not use add in multiprocessing')
368
+ >>> import multiprocessing
369
+ >>> p = multiprocessing.Process(
370
+ ... target=lambda a, b: a + b,
371
+ ... args=(1, 2),
372
+ ... )
373
+ >>> p.start()
374
+ >>> p.join()
375
+
376
+ ```
377
+
378
+ 此时,示例单独在主进程中运行检查,并能正常通过。
379
+
380
+ ** 注意** : 使用 ` SOLO ` 指令时,由于主进程环境没有特殊的运行前和运行后处理,因此,如果一次运行多个 ` SOLO ` 的示例,需要事先确认各个示例间不会相会影响。
381
+
382
+
383
+ ## 参考资料
310
384
- [ 「将 xdoctest 引入到飞桨框架工作流中」 RFC] ( https://github.com/PaddlePaddle/community/blob/master/rfcs/Docs/%E5%B0%86%20xdoctest%20%E5%BC%95%E5%85%A5%E5%88%B0%E9%A3%9E%E6%A1%A8%E6%A1%86%E6%9E%B6%E5%B7%A5%E4%BD%9C%E6%B5%81%E4%B8%AD.md )
311
385
- [ 「将 xdoctest 引入到飞桨框架工作流中」 详细设计] ( https://github.com/PaddlePaddle/Paddle/blob/develop/tools/sampcd_processor_readme.md )
312
386
- [ 「doctest」官方文档 ] ( https://docs.python.org/3/library/doctest.html#module-doctest )
0 commit comments