贡献 Python 代码#

Bokeh 代码库结合了用 Python 和 TypeScript 编写的代码。本章概述了在处理 Bokeh 的 Python 代码时需要了解的最重要事项。

代码风格#

Bokeh 的 Python 代码通常遵循 PEP8 标准。一些值得注意的例外包括

Bokeh 使用每个 拉取请求 的代码质量测试组合。与 Python 代码相关的测试包括 Ruffisort。使用以下命令在本地运行这些代码库测试

pytest tests/codebase

要详细了解如何在您的系统上运行这些测试,请参见 运行代码库测试

测试#

所有添加或更新代码的 拉取请求 应包含新的或更新的测试。有关测试的更多信息(包括 Python 特定测试),请参见 运行测试编写测试

源代码组织#

Bokeh 存储库包含 Bokeh 的 Python 代码以及 BokehJS 的 JavaScript 代码。以下是包含 Python 代码的最相关文件夹

src/bokeh/

Bokeh 库本身的 Python 代码位于 src/bokeh 文件夹中。

构成 Bokeh 可视化的所有内容(例如 工具图形小部件列数据源)都基于 Bokeh 模型。所有模型的 Python 代码位于 src/bokeh/models 中。有关模型的更多信息,请参见下面的 模型和属性

此文件夹中的其他子目录包括

有关此目录及其子目录结构的更多信息,请参见 参考指南

examples/

examples 文件夹包含 Bokeh 大多数功能的示例。其中一些示例在 Bokeh 的 画廊 中使用。

tests/

tests 文件夹包含 Bokeh 的测试套件。有关测试的更多信息,请参见 运行测试编写测试

typings/

src/typings 文件夹包含 Bokeh 类型提示的 存根文件

模型和属性#

所有 Bokeh 可视化的核心构建块是基于 Bokeh 模型 的对象。这些模型是 绘图 元素的表示,例如 图形小部件

在 Python 端,Bokeh 将每个绘图元素对象的属性序列化为 JSON 数据。在浏览器端,BokehJS 反序列化此 JSON 数据并根据此信息创建 JavaScript 对象。然后,BokehJS 使用这些 JavaScript 对象来渲染可视化。

Flowchart describing the flow of data from Python objects through JSON to the browser-side. There, the JSON data is converted into JavaScript objects which then get rendered as output. Output can be HTML Canvas, WebGL, or SVG.

每当您更新或添加 Python 中的模型时,您还需要 更新 BokehJS 的对应 TypeScript 代码

Bokeh 的所有 Python 模型都位于 src/bokeh/models 及其子文件夹中。它们都是 Model 的子类

class SomeNewModel(Model):
    """ Some new model. """

模型包含属性,这些属性是在 bokeh.core.properties 中定义的类属性。例如

class ModelWithIntProps(Model):
    prop1 = Int()
    prop2 = Int(10)

在此示例中,ModelWithIntProps 模型表示具有两个整数值 prop1prop2 的对象。

Bokeh 使用各种各样的属性类型

  • 原始类型,如 ByteIntFloatComplexString

  • 将其他属性作为参数的容器类属性,例如 List (List(Int)) 或 Dict (Dict(String, Double))

  • 专门类型,如 Instance (Instance(Plot))、Enum (Enum("foo", "bar", "baz")) 或 Either (Either(Int, String))

这些属性类型有几个用途

  • 类型检查 不同的模型

  • 确保模型在 Python 和 JavaScript 之间保持兼容

  • 自动为 参考指南 生成一些基本文档

更现实的模型示例可能如下所示

class SomeModel(Model):
    prop1 = Int(127)
    prop2 = Either(Int, List(Int), Dict(String, List(Int)))
    prop3 = Enum("x", "y", "z")
    prop4 = Range(Float, 0.0, 1.0)
    prop5 = List(Instance(Range1d))

有关更多详细信息,请参见 bokeh.core.properties

警告

Any 是所有其他类型的超类型,并且将接受任何类型的 value。由于这绕过了所有类型验证,因此请确保谨慎使用它,如果有的话。

类型提示#

Bokeh 使用两个系统来检查 Python 代码的类型

  • 对于 上面描述的模型系统,Bokeh 使用它自己的属性系统。有关更多信息,请参见 模型和属性

  • 对于任何不使用模型的代码,Bokeh 使用 PEP 484 样式提示。如有必要,请使用 Python 标准的 typingtyping_extensions 模块。

Bokeh 的 CI 使用 mypy 检查类型。要在本地检查代码类型,请运行 mypy bokeh

注意

如果您想将类型信息与 mypy 以外的工具一起使用(例如,使用 typing.get_type_hints 提取信息),您很可能需要使用 Python 3.10 或更高版本。这是因为 Bokeh 的一些类型提示使用 X | Y 语法来表示联合类型,如 PEP 604 中所定义。