# https://github.com/beanbaginc/housekeeping 项目说明书

生成时间：2026-06-14 16:30:26 UTC

## 目录

- [项目概览](#page-1)
- [安装与项目集成](#page-2)
- [基类与弃用警告体系](#page-3)
- [内部架构与数据流](#page-4)
- [函数与方法弃用](#page-5)
- [类弃用与迁移](#page-6)
- [模块弃用](#page-7)
- [版本、迁移与常见问题](#page-8)

<a id='page-1'></a>

## 项目概览

### 相关页面

相关主题：[安装与项目集成](#page-2), [基类与弃用警告体系](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md)
- [housekeeping/__init__.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py)
- [housekeeping/_version.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/_version.py)
- [housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)
- [housekeeping/classes.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py)
- [housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)
- [housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)
- [housekeeping/helpers.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)
</details>

# 项目概览

## 简介与设计目标

Housekeeping 是一个轻量级的 Python 工具库，专门用于在项目中标记已被废弃（deprecated）或即将被废弃（pending deprecation）的代码，并为使用者提供清晰的迁移指引。它以装饰器、混入类（mixin）和工具函数的形式，封装了 Python 标准库 `warnings` 模块的常见用法，避免各项目重复实现同一套弃用通知逻辑。

该库源于 Review Board、Djblets 与 RBTools 等项目在多年演进过程中积累的经验，旨在以一致的方式管理函数、方法、类、模块、参数以及字典键等各类弃用场景。资料来源：[README.md:1-15]()

Housekeeping 遵循 [语义化版本](https://semver.org/)，被设计为以依赖项形式嵌入到宿主项目中使用：

```console
$ pip install housekeeping
```

资料来源：[README.md:19-30]()

## 代码组织与模块结构

仓库的 Python 包主体集中在 `housekeeping/` 目录下，按职责拆分为若干子模块。`__init__.py` 负责将各子模块的公共 API 统一暴露给调用方，并定义了 `__all__` 列表来显式声明对外接口。资料来源：[housekeeping/__init__.py:27-66]()

下表列出了各子模块的核心职责：

| 子模块 | 主要职责 | 关键导出 |
| --- | --- | --- |
| `housekeeping._version` | 版本号与包元信息 | `VERSION`、`get_version_string()`、`get_package_version()` |
| `housekeeping.base` | 弃用警告基类与类型别名 | `BaseDeprecationWarningMixin`、`BasePendingRemovalWarning`、`BaseRemovedInWarning`、`DeprecationWarningType` |
| `housekeeping.classes` | 类级别的弃用混入类 | `ClassDeprecatedMixin`、`ClassMovedMixin` |
| `housekeeping.functions` | 函数/方法/参数弃用工具 | `func_deprecated`、`func_moved`、`deprecate_non_keyword_only_args`、`deprecated_arg_value` |
| `housekeeping.modules` | 模块级弃用工具 | `module_deprecated`、`module_moved` |
| `housekeeping.helpers` | 内部辅助实现（非公开 API） | `LazyObject`、`emit_warning`、`format_display_name` |

资料来源：[housekeeping/__init__.py:27-66]()、[housekeeping/base.py:1-30]()、[housekeeping/classes.py:1-10]()、[housekeeping/functions.py:1-20]()、[housekeeping/modules.py:1-15]()

`helpers.py` 模块的文档字符串明确指出该模块"不是公共 API，可能发生变更"，因此使用者应仅依赖 `housekeeping` 顶层命名空间中重新导出的接口。资料来源：[housekeeping/helpers.py:1-5]()

## 弃用分层与公共 API

Housekeeping 将弃用语义划分为两个层级：正式的"弃用警告"（明确将在某个具体版本中移除）与"待定弃用警告"（尚无明确移除时间，但计划在未来的某个版本中转为正式弃用）。`base.py` 提供了 `BasePendingRemovalWarning` 与 `BaseRemovedInWarning` 两个混入基类，使用者应当在自家项目中继承它们以定义面向自家产品的告警类。资料来源：[housekeeping/base.py:1-50]()、[README.md:41-72]()

在具体代码位置触发弃用时，调用方只需传入一个 `warning_cls` 参数。`base.py` 通过类型别名 `DeprecationWarningTypeOrCallable` 同时支持传入告警类本身，或传入一个返回告警类的可调用对象，以避免循环引用问题。资料来源：[housekeeping/base.py:1-30]()

```mermaid
flowchart LR
    A[调用方代码] --> B{弃用对象类型}
    B -- 函数/方法 --> C[functions.py]
    B -- 类 --> D[classes.py]
    B -- 模块 --> E[modules.py]
    C --> F[helpers.emit_warning]
    D --> F
    E --> F
    F --> G[base.BaseDeprecationWarningMixin.warn]
    G --> H[Python warnings 模块]
```

`ClassDeprecatedMixin` 与 `ClassMovedMixin` 会在类首次被子类化或直接实例化时发出告警；但在子类上再次派生时，混入类会通过 `__init_subclass__` 内部机制避免重复告警，从而让迁移路径保持安静。资料来源：[housekeeping/classes.py:1-80]()

## 版本演进与社区关注点

当前开发版本的元信息在 `_version.py` 中以六元组形式维护，主版本为 1、次版本为 2、微版本为 0、标签为 `alpha`、发布序号为 0，且尚未发布（`False`）。`get_version_string()` 与 `get_package_version()` 分别用于生成面向用户展示的版本字符串与面向打包工具的 PEP 440 兼容版本字符串。资料来源：[housekeeping/_version.py:1-50]()

社区近期关注的 1.1 版本重点解决了"基类迁移时的告警风暴"问题：

- 子类可以通过设置 `housekeeping_skip_warning = True` 类属性，跳过由父混入类发出的弃用告警，从而在内部重构时不再骚扰调用方。
- `warning_cls` 参数现在可以传入一个返回告警类的函数（callable），以打破因告警类定义与被弃用对象位于同一模块而形成的循环导入。

资料来源：[README.md（社区上下文，Housekeeping 1.1 发布说明）]()

这两个变化都已在 `base.py` 的 `DeprecationWarningTypeOrCallable` 类型别名中体现：参数注释明确指出"自 1.1 起，可传入告警类或返回告警类的函数"。资料来源：[housekeeping/base.py:1-30]()、[housekeeping/functions.py:1-60]()、[housekeeping/modules.py:1-60]()

## See Also

- 警告基类与类型系统：[housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)
- 函数与参数弃用：[housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)
- 类与模块弃用：[housekeeping/classes.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py)、[housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)
- 公共 API 入口：[housekeeping/__init__.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py)

---

<a id='page-2'></a>

## 安装与项目集成

### 相关页面

相关主题：[项目概览](#page-1), [基类与弃用警告体系](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md)
- [housekeeping/_version.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/_version.py)
- [housekeeping/__init__.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py)
- [housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)
- [housekeeping/classes.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py)
- [housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)
- [housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)
- [housekeeping/helpers.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)
</details>

# 安装与项目集成

Housekeeping 是一个轻量级的 Python 工具库，专门用于在代码库中标记已弃用（deprecated）或即将弃用（pending deprecation）的功能，并向使用者提供清晰、可操作的迁移提示。该库起源于 [Review Board](https://www.reviewboard.org)、[Djblets](https://github.com/djblets/djblets) 和 [RBTools](https://www.reviewboard.org/downloads/rbtools/) 在长期演进过程中沉淀的最佳实践，旨在为项目作者与消费者提供统一、可控的弃用生命周期管理能力。资料来源：[README.md:1-10]()

## 安装方式

Housekeeping 被打包为一个标准的 Python 工具库（utility library），通常作为项目的运行时依赖被引入。它遵循 [语义化版本（Semantic Versioning）](https://semver.org/) 规范，升级时不会出现非预期的破坏性变更。资料来源：[README.md:18-23]()

最常见的安装方式是通过 `pip`：

```console
$ pip install housekeeping
```

资料来源：[README.md:20-22]()

库当前对外暴露的版本元数据由 [`housekeeping/_version.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/_version.py) 维护，版本号采用 `(Major, Minor, Micro, tag, release_num, released)` 的元组结构。其中 `get_version_string()` 用于生成可读的展示版本（如 `1.2 alpha 0 (dev)`），而 `get_package_version()` 用于生成符合 PEP 440 的打包版本（如 `1.2a0`）。资料来源：[housekeeping/_version.py:6-58]()

## 项目内的初始化与配置

在将 Housekeeping 集成到项目后，第一步是为该项目定义一组**项目专属的弃用基类**。这通常被放置在 `<project_name>.deprecation` 模块中，以便全项目统一引用。资料来源：[README.md:30-44]()

Housekeeping 区分两类弃用：

| 类别 | 含义 | 适用基类 |
| ---- | ---- | ---- |
| 弃用警告（Deprecation） | 已弃用，并将在某个特定版本中移除 | `BaseRemovedInWarning` |
| 待弃用警告（Pending Deprecation） | 尚可用，但将在未来某个版本弃用 | `BasePendingRemovalWarning` |

资料来源：[README.md:30-44]()、[housekeeping/base.py:67-79]()

`BaseDeprecationWarningMixin` 提供了所有弃用类的统一行为约束：每个子类必须设置 `product`（项目名称）和 `version`（计划移除的版本）这两个类属性，否则在发出警告时会出现格式化错误。资料来源：[housekeeping/base.py:21-29]()

典型的项目集成方式如下：

```python
from housekeeping import BasePendingRemovalWarning, BaseRemovedInWarning

class PendingRemovalInMyProjectWarning(BasePendingRemovalWarning):
    project = 'My Project'

class BaseRemovedInMyProjectWarning(BaseRemovedInWarning):
    project = 'My Project'

class RemovedInMyProject20Warning(BaseRemovedInMyProjectWarning):
    version = '2.0'

class RemovedInMyProject30Warning(BaseRemovedInMyProjectWarning):
    version = '3.0'
```

资料来源：[README.md:46-69]()

随后即可在任何模块、函数或类中通过这些项目级警告类触发弃用通知。例如，使用 `module_moved` 在旧的模块体中引导消费者切换到新位置：

```python
from housekeeping import module_moved
from myproject.deprecation import RemovedInMyProject20Warning
from myproject import newmodule

module_moved(RemovedInMyProject20Warning, __name__, newmodule.__name__)
```

资料来源：[README.md:71-82]()、[housekeeping/modules.py:69-103]()

## 公共 API 与集成入口

Housekeeping 鼓励使用者直接从顶层包导入所需的工具函数和类，以避免在代码中暴露内部实现细节。资料来源：[housekeeping/__init__.py:1-19]()

`housekeeping/__init__.py` 显式导出了下列公共符号（节选自 `__all__`）：

- 警告基类：`BaseDeprecationWarningMixin`、`BasePendingRemovalWarning`、`BaseRemovedInWarning`
- 类级别弃用：`ClassDeprecatedMixin`、`ClassMovedMixin`
- 函数级别弃用：`deprecate_non_keyword_only_args`、`deprecated_arg_value`、`func_deprecated`、`func_moved`
- 模块级别弃用：`module_deprecated`、`module_moved`
- 版本元数据：`VERSION`、`__version__`、`is_release` 等

资料来源：[housekeeping/__init__.py:25-65]()

整体集成路径可以概括为下图所示的工作流：

```mermaid
flowchart LR
    A[安装 housekeeping] --> B[定义项目级 deprecation 基类]
    B --> C[在旧代码上打标记<br/>module / func / class]
    C --> D[消费者触发弃用警告]
    D --> E[迁移到新 API]
    E --> F[到达 version 后移除旧代码]
```

## 常见集成注意事项

在将 Housekeeping 集成到现有项目时，有以下几点需要特别留意：

1. **避免循环引用。** 由于弃用基类经常需要引用项目自身的模块，建议将 `myproject.deprecation` 放在依赖链的最底层。自 1.1 起，`warning_cls` 参数可以接受一个返回警告类的可调用对象，从而推迟解析时机以打破循环导入。资料来源：[README.md（社区上下文 Housekeeping 1.1 发布说明）]()、[housekeeping/base.py:90-95]()

2. **控制警告栈深度。** 所有内部辅助函数都会自动在用户传入的 `stacklevel` 之上加 1，以确保警告的来源指向调用方代码而非 Housekeeping 自身。如果自定义包装层数较深，请相应增加 `stacklevel`。资料来源：[housekeeping/helpers.py:128-149]()、[housekeeping/modules.py:42-50]()

3. **子类抑制警告。** 自 1.1 起，子类可以通过在自身上设置 `housekeeping_skip_warning = True` 来避免继承链上重复触发弃用警告，适用于在内部大量复用已弃用基类的场景。资料来源：[README.md（社区上下文 Housekeeping 1.1 发布说明）]()

4. **License 与再分发。** Housekeeping 基于 MIT 协议发布，可以自由用于闭源或开源项目中。资料来源：[README.md:26-28]()

完成上述步骤后，弃用策略即可在项目中以统一、可追溯的方式运行：旧的代码入口会主动告知消费者其计划移除的版本与替代方案，从而在不破坏既有使用者的前提下稳步推进 API 演进。

---

<a id='page-3'></a>

## 基类与弃用警告体系

### 相关页面

相关主题：[安装与项目集成](#page-2), [函数与方法弃用](#page-5), [类弃用与迁移](#page-6)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)
- [housekeeping/classes.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py)
- [housekeeping/helpers.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)
- [housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)
- [housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)
- [housekeeping/__init__.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py)
- [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md)
- [housekeeping/_version.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/_version.py)
</details>

# 基类与弃用警告体系

## 概述

Housekeeping 是一个用于在 Python 项目中标记"已弃用"与"待弃用"代码的实用库，其核心是一套以 `BaseDeprecationWarningMixin` 为基础的警告类型层次结构，并配合 `ClassDeprecatedMixin`、`ClassMovedMixin` 等类级别的 Mixin 使用户在子类化或实例化时自动收到警告提示。整套体系通过统一的 `emit_warning` 内部帮助函数向外发出 `DeprecationWarning` 或 `PendingDeprecationWarning`，从而覆盖函数、方法、类、模块、参数以及字典键等多种弃用场景 资料来源：[README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md)。

当前库版本为 `1.2.0 alpha 0`，自 1.1 版本起新增了两项关键改进以帮助子类平滑迁移：子类可通过设置 `housekeeping_skip_warning = True` 跳过警告；`warning_cls` 既可为警告类型，也可为返回警告类型的可调用对象 资料来源：[housekeeping/_version.py:10-14]() 资料来源：[housekeeping/classes.py]("https://github.com/beanbaginc/housekeeping/releases/tag/release-1.1")。

## 警告类型层次结构

弃用警告体系的基础在 [housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py) 中定义。`BaseDeprecationWarningMixin` 是所有项目自定义警告类的根混合类，提供三个核心类属性：`product`（产品名）、`version`（移除版本）、`version_required`（是否必须指定版本），并通过 `warn()` 类方法以 `DEFAULT_STACK_LEVEL = 2` 的栈层发出警告 资料来源：[housekeeping/base.py:24-60]()。

在此基础上派生出两类具体基类：

- `BasePendingRemovalWarning`：继承自 `BaseDeprecationWarningMixin` 与 `PendingDeprecationWarning`，用于标记"未来版本可能弃用"的功能。
- `BaseRemovedInWarning`：继承自 `BaseDeprecationWarningMixin` 与 `DeprecationWarning`，用于标记"将在特定版本移除"的功能，要求子类必须设置 `version` 字段。

类型别名 `DeprecationWarningType` 表示 `Type[DeprecationWarning]`，而 `DeprecationWarningTypeOrCallable` 则是其与 `Callable[..., DeprecationWarningType]` 的并集，允许通过函数延迟解析警告类以避免循环引用 资料来源：[housekeeping/base.py]("https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py")。

类之间的继承关系如下：

```mermaid
classDiagram
    class DeprecationWarning
    class PendingDeprecationWarning
    class BaseDeprecationWarningMixin {
        +product: str
        +version: str
        +version_required: bool
        +warn() classmethod
    }
    class BasePendingRemovalWarning
    class BaseRemovedInWarning
    class ClassDeprecatedMixin
    class ClassMovedMixin

    DeprecationWarning <|-- BaseRemovedInWarning
    PendingDeprecationWarning <|-- BasePendingRemovalWarning
    BaseDeprecationWarningMixin <|-- BasePendingRemovalWarning
    BaseDeprecationWarningMixin <|-- BaseRemovedInWarning
    BaseDeprecationWarningMixin ..> ClassDeprecatedMixin : 被引用
    BaseDeprecationWarningMixin ..> ClassMovedMixin : 被引用
```

## 类级别的弃用 Mixin

针对"整个类被弃用"或"整个类被迁移"两种场景，[housekeeping/classes.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py) 提供了两个 Mixin：

| Mixin | 触发时机 | 关键参数 | 默认行为 |
|-------|----------|----------|----------|
| `ClassDeprecatedMixin` | 直接子类化或直接实例化时 | `warning_cls`、`subclass_deprecation_msg`、`init_deprecation_msg` | 子类与初始化分别发出对应警告 |
| `ClassMovedMixin` | 直接子类化时，建议改用新基类 | `warning_cls`、`deprecation_msg`、`new_base_cls` | 警告中提示切换到新基类 |

两者均通过 `__init_subclass__` 钩子识别"是否直接继承自 Mixin"，仅对第一级子类和直接初始化发出警告；多级继承下的孙子类不会重复提示 资料来源：[housekeeping/classes.py:80-150]()。子类若不希望被警告，可设置类属性 `housekeeping_skip_warning = True`，这是 1.1 版本中明确加入的"静默迁移"能力 资料来源：[housekeeping/classes.py]("https://github.com/beanbaginc/housekeeping/releases/tag/release-1.1")。

当 `ClassDeprecatedMixin` 在 `__bases__` 中时，Mixin 会强制要求声明 `warning_cls=...`，否则抛出 `AssertionError` 资料来源：[housekeeping/classes.py:120-128]()。

## 内部帮助函数与运行时机制

实际的警告发射由 [housekeeping/helpers.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py) 中的 `emit_warning` 完成。它会判断 `warning_cls` 是直接类型还是可调用对象，解析后构造对应的去弃用或待弃用消息，并使用 `warnings.warn` 发出。同时为解决"何时实例化值"的延迟需求，库内置了 `LazyObject` 泛型包装器，第一次访问被包装的属性时才会真正发出警告——`deprecated_arg_value` 即基于此实现 资料来源：[housekeeping/helpers.py:1-80]() 资料来源：[housekeeping/functions.py:1-60]()。

函数与模块层面的弃用（`func_deprecated`、`func_moved`、`module_deprecated`、`module_moved`、`deprecate_non_keyword_only_args`）全部共享同一套 `warning_cls` 协议，并允许传入 `message` 自定义消息与 `stacklevel` 微调栈层 资料来源：[housekeeping/functions.py]("https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py") 资料来源：[housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)。

所有这些类型与函数都通过 `housekeeping/__init__.py` 的 `__all__` 集中对外导出，用户可直接 `from housekeeping import ...` 使用 资料来源：[housekeeping/__init__.py:48-66]()。

## 典型用法与失败模式

README 推荐的使用模式是：项目先在自身 `deprecation` 模块继承 `BasePendingRemovalWarning` 与 `BaseRemovedInWarning`，再按版本号派生出 `RemovedInMyProject20Warning` 等具体类，然后在被弃用的类、函数、模块上分别挂接对应 Mixin 或装饰器 资料来源：[README.md]("https://github.com/beanbaginc/housekeeping/blob/main/README.md")。

常见失败模式包括：

- **忘记设置 `warning_cls`**：在 `ClassDeprecatedMixin` 的 `__init_subclass__` 中会因为断言失败而报错 资料来源：[housekeeping/classes.py:120-128]()。
- **警告类型来自循环引用模块**：此时应改用可调用对象形式传入 `warning_cls`，1.1 版本明确支持该用法。
- **期望孙类也收到警告**：体系默认仅在直接子类化时警告一次，多级继承不会重复提示；若确实需要强制提示，请勿设置 `housekeeping_skip_warning`。

## 参见

- [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md) — 项目总体说明与快速上手。
- [Housekeeping 1.1 Release Notes](https://github.com/beanbaginc/housekeeping/releases/tag/release-1.1) — `housekeeping_skip_warning` 与可调用 `warning_cls` 的引入说明。

---

<a id='page-4'></a>

## 内部架构与数据流

### 相关页面

相关主题：[基类与弃用警告体系](#page-3), [函数与方法弃用](#page-5)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [housekeeping/__init__.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py)
- [housekeeping/_version.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/_version.py)
- [housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)
- [housekeeping/helpers.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)
- [housekeeping/classes.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py)
- [housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)
- [housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)
- [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md)
</details>

# 内部架构与数据流

## 概述与设计目标

Housekeeping 是一个专注于 Python 代码弃用（deprecation）管理的实用库，其内部架构围绕「统一的警告发射机制」和「按弃用对象类型分层的辅助 API」展开。库本身不参与业务流程，仅在被弃用的代码被实际调用、继承、导入或读取时，触发 Python 标准 `warnings` 模块发出通知。

项目的公开 API 在 [housekeeping/__init__.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py) 中以单一入口聚合导出，包括 `BasePendingRemovalWarning`、`BaseRemovedInWarning`、`ClassDeprecatedMixin`、`ClassMovedMixin`、`func_deprecated`、`func_moved`、`module_deprecated`、`module_moved` 等核心符号，从而避免使用者直接接触内部模块路径。

## 模块分层与职责划分

Housekeeping 的源码按职责可划分为三层：基础类型层、辅助工具层、面向对象的弃用辅助层。

| 层级 | 模块 | 主要职责 |
|------|------|----------|
| 基础类型层 | `housekeeping/base.py` | 定义 `BaseDeprecationWarningMixin`、`BasePendingRemovalWarning`、`BaseRemovedInWarning` 以及 `DeprecationWarningType`、`DeprecationWarningTypeOrCallable` 类型别名 |
| 辅助工具层 | `housekeeping/helpers.py` | 实现内部 `emit_warning`、`LazyObject`、`format_display_name` 等通用逻辑，被其他模块复用 |
| 弃用辅助层 | `housekeeping/functions.py`、`housekeeping/classes.py`、`housekeeping/modules.py` | 针对函数/方法、类、模块三种 Python 对象提供装饰器、Mixin 与函数 |

`housekeeping/_version.py` 独立保存版本元组 `(1, 2, 0, 'alpha', 0, False)` 与格式化函数，便于发行打包时引用，不参与运行时警告流。

## 核心数据流：从弃用调用到 `warnings.warn`

所有公开弃用辅助工具最终都收敛到 `helpers.emit_warning` 这一中心函数。下面以函数弃用为例说明完整数据流：

```mermaid
flowchart TD
    A["用户调用被装饰函数<br/>(例如 my_func())"] --> B["func_deprecated 装饰器包装层"]
    B --> C["emit_warning(warning_cls, deprecation_msg, ...)<br/>位于 housekeeping/helpers.py"]
    C --> D{"warning_cls 是类型还是可调用对象?"}
    D -- 类型 --> E["BaseDeprecationWarningMixin.warn"]
    D -- 可调用对象 --> F["调用可调用对象获取类型<br/>(Housekeeping 1.1 新增)"]
    F --> E
    E --> G["warnings.warn(message, category, stacklevel+1)"]
    G --> H["Python warnings 模块<br/>触发 DeprecationWarning 或 PendingDeprecationWarning"]
```

关键流程细节如下：

1. **入口分发**：[housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py) 中的 `func_deprecated` 使用 `functools.wraps` 包裹原函数，并在调用时把控制权交给 `emit_warning`，随后才执行原函数体。
2. **类型规范化**：`emit_warning` 接受 `DeprecationWarningTypeOrCallable`，在 1.1 版本中支持传入「返回警告类的可调用对象」，用以规避循环引用问题。规范来源：[housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py) 中 `module_deprecated` 的 `warning_cls` 文档说明。
3. **子类抑制**：在 [housekeeping/classes.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py) 中，`ClassDeprecatedMixin` 与 `ClassMovedMixin` 通过 `__init_subclass__` 钩子在子类化时检测 `housekeeping_skip_warning = True` 属性，若设置则跳过警告发射，这是 1.1 版本发布说明中提到的关键增强。
4. **栈帧调整**：所有弃用助手都在内部对 `stacklevel` 加 1（参见 [housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py) 中 `module_moved` 的 `stacklevel=stacklevel + 1`），以保证警告指向调用方而非 Housekeeping 内部。

## 类型系统与基类关系

`housekeeping/base.py` 定义了项目最核心的抽象。`BaseDeprecationWarningMixin` 在类型检查环境下继承自 `DeprecationWarning`/`PendingDeprecationWarning`，运行时则退化为 `object`，从而避免污染用户的 `warnings.filterwarnings` 过滤规则（资料来源：[housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py) 中 `if TYPE_CHECKING` 分支）。

`BaseDeprecationWarningMixin` 通过 `product`、`version`、`version_required` 类属性描述「哪个项目、在哪个版本将被移除」，并提供 `warn(message, stacklevel, **kwargs)` 类方法作为标准发射接口。`BasePendingRemovalWarning` 与 `BaseRemovedInWarning` 分别代表「未来会被弃用」与「已计划在特定版本移除」两类语义，由消费项目继承并填入具体版本号（如 `RemovedInMyProject20Warning`）。

## 辅助机制：`LazyObject` 与按需警告

[housekeeping/helpers.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py) 中的 `LazyObject` 是针对「参数值弃用」场景设计的惰性代理，典型用法见 `deprecated_arg_value`（[housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)）。它只在外部真正访问被包装值时才实例化对象并发射警告，从而避免仅传参而不读取时产生噪音。

## 常见故障模式

- **循环导入**：直接在弃用助手调用处写 `RemovedInMyProject20Warning` 字面量，可能在模块加载期触发循环引用；1.1 版本后推荐传入返回类的可调用对象。
- **错误的 `stacklevel`**：若用户自定义装饰器再次包裹 Housekeeping 装饰器，应手动提升 `stacklevel`，否则警告会指向装饰器链中的内部函数。
- **子类误触发**：`ClassMovedMixin` 的子类继承检测仅在「直接子类化」时触发一次，跨层继承不会重复警告；若希望彻底关闭，需在子类设置 `housekeeping_skip_warning = True`。

## See Also

- [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md) — 项目介绍与基础使用示例
- [Housekeeping 1.1 Release Notes](https://github.com/beanbaginc/housekeeping/releases/tag/release-1.1) — `housekeeping_skip_warning` 与可调用 `warning_cls` 的引入说明

---

<a id='page-5'></a>

## 函数与方法弃用

### 相关页面

相关主题：[基类与弃用警告体系](#page-3), [类弃用与迁移](#page-6)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)
- [housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)
- [housekeeping/helpers.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)
- [housekeeping/__init__.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py)
- [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md)
- [housekeeping/_version.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/_version.py)
</details>

# 函数与方法弃用

## 概述

Housekeeping 是一个专注于 Python 项目弃用管理的工具库，其核心能力之一是为函数与方法提供声明式、可定制、可推迟的弃用标记机制。该能力集中实现于 `housekeeping/functions.py` 模块，并通过 `housekeeping/__init__.py` 直接对外暴露 [`func_deprecated`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)、[`func_moved`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)、[`deprecated_arg_value`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py) 和 [`deprecate_non_keyword_only_args`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py) 四个公共 API。

这些工具共同解决了三类常见的函数级演进场景：标记即将删除的函数、指引迁移到新位置的函数，以及将位置参数升级为关键字参数。底层则通过 [`BaseDeprecationWarningMixin`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py) 中定义的 `product`、`version`、`warn()` 通道，与项目自身的弃用类协作。当前版本（截至 [`housekeeping/_version.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/_version.py)）为 `1.2.0 alpha 0`。

## 核心装饰器：func_deprecated 与 func_moved

### func_deprecated

[`func_deprecated`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py) 返回一个装饰器工厂。被装饰函数在被调用时会先通过 [`emit_warning`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py) 发出警告，再继续执行原函数。默认消息模板由 `deprecation_msg` 与 `pending_deprecation_msg` 控制：

- 已弃用：`` `%(func_name)s` is deprecated and will be removed in %(product)s %(version)s. ``
- 待弃用：`` `%(func_name)s` is scheduled to be deprecated in a future version of %(product)s. ``

`func_name` 由 [`format_display_name`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py) 解析，从而保证方法绑定名（如 `MyClass.method`）能正确呈现。可选参数 `message` 可覆盖默认模板，`stacklevel` 默认为 `DEFAULT_STACK_LEVEL`（取值见 [`housekeeping/base.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)）。

### func_moved

[`func_moved`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py) 与 `func_deprecated` 形态类似，但额外接受 `new_func` 参数（可以是字符串描述或可调用对象），用于在告警中告知调用者迁移目标。两种状态的默认消息分别为：

- 已弃用：`` `<old_func_name>` has moved to `<new_func_name>`. The old function is deprecated and will be removed in <product> <version>. ``
- 待弃用：`` `<old_func_name>` has moved to `<new_func_name>`. The old function is scheduled to be deprecated in a future version of <product>. ``

社区版本说明（Housekeeping 1.1）指出，自该版本起 `warning_cls` 既可以是警告类，也可以是返回警告类的可调用对象，便于打破循环引用。

## 参数演进：deprecated_arg_value 与 deprecate_non_keyword_only_args

当弃用目标不是函数本身，而是传递给消费者回调的参数值或位置参数语义时，需要不同的处理手段。

`deprecated_arg_value`（[functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)）将任意值包装进 [`LazyObject`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)：该代理仅在被消费者真正访问时才会触发 `emit_warning`，因此对热路径性能友好。签名要求 `owner_name`、`value`、`old_name` 三项必填；当传入 `new_name` 时，消息会自动追加迁移提示，否则只描述弃用事实。

`deprecate_non_keyword_only_args`（[README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md) 中示例）用于把旧式的位置参数强制迁移为关键字参数，典型用法：

```python
@deprecate_non_keyword_only_args(RemovedInMyProject20Warning)
def add_abc(a, *, b, c=1):
    return a + b + c
```

当调用方仍以位置方式传入 `b`、`c` 时，装饰器会发出警告，提示其改用关键字形式。

## 警告机制与共享基础设施

所有函数级弃用 API 都汇聚到 [`emit_warning`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)，它会校验 `warning_cls` 是否为 `DeprecationWarning` 或 `PendingDeprecationWarning` 的子类，并据此选择 `deprecation_msg` 或 `pending_deprecation_msg`。随后调用 `BaseDeprecationWarningMixin.warn()`（[base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)），由项目方定义的 `product` 与 `version` 字段填充消息模板。`stacklevel` 在每一层包装函数中递增一次，以保证 Python `warnings` 模块指向真实的调用方。

下表总结了函数级弃用工具的职责边界：

| 工具 | 触发时机 | 适用场景 |
|------|---------|---------|
| `func_deprecated` | 函数被调用时 | 标记未来版本将被移除 |
| `func_moved` | 函数被调用时 | 告知迁移到新函数 |
| `deprecated_arg_value` | 包装值首次被访问时 | 回调、字典键等间接传递 |
| `deprecate_non_keyword_only_args` | 位置参数被传入时 | 位置→关键字参数升级 |

## See Also

- [模块弃用](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py) — `module_deprecated`、`module_moved` 与函数级 API 共享同一套警告基础设施。
- [类弃用](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py) — `ClassDeprecatedMixin`、`ClassMovedMixin` 通过元类机制实现类级别的弃用。
- [Housekeeping 1.1 Release Notes](https://github.com/beanbaginc/housekeeping/releases/tag/release-1.1) — 介绍了 `housekeeping_skip_warning` 与可调用 `warning_cls` 的新约定。

---

<a id='page-6'></a>

## 类弃用与迁移

### 相关页面

相关主题：[基类与弃用警告体系](#page-3), [函数与方法弃用](#page-5), [版本、迁移与常见问题](#page-8)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [housekeeping/classes.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py)
- [housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)
- [housekeeping/helpers.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)
- [housekeeping/__init__.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py)
- [housekeeping/_version.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/_version.py)
- [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md)
- [housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)
- [housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)
</details>

# 类弃用与迁移

## 概述

`housekeeping` 是一个帮助 Python 项目标记「已弃用」与「待迁移」代码的工具库，由 Review Board、Djblets 与 RBTools 团队基于长期维护经验提炼 资料来源：[README.md:1-15]()。其核心子能力之一是「类弃用与迁移」，由 `housekeeping.classes` 模块中的两个 Mixin ——`ClassDeprecatedMixin` 与 `ClassMovedMixin`——提供，分别用于告知消费者「某个类已废弃」或「某个类已迁出，请改用新基类」。

类弃用与迁移机制会同时覆盖「直接实例化」与「直接继承」两种触发场景，并通过 `housekeeping.base` 中的警告基类提供统一的告警文本格式（产品名、移除版本）。

## 弃用警告基类

类弃用依赖于一套可复用的警告类层级，定义在 `housekeeping.base` 中 资料来源：[housekeeping/base.py]()：

- `BaseDeprecationWarningMixin`：混入类，提供 `product`（产品名）、`version`（移除版本）以及 `warn()` 便捷方法。在类型检查阶段会混合 `DeprecationWarning` / `PendingDeprecationWarning`，运行期退化为 `object`，避免与用户自定义 `Warning` 冲突。
- `BasePendingRemovalWarning`：表示「未来某版本会弃用」。
- `BaseRemovedInWarning`：表示「在指定版本中将被移除」，子类需提供 `version` 字段。

调用方可在项目中继承这两个基类来构建自己的警告体系，例如 `RemovedInMyProject20Warning` 资料来源：[README.md:51-69]()。

## ClassDeprecatedMixin — 标记类被弃用

`ClassDeprecatedMixin` 在类被「直接实例化」或「直接继承」时发出警告 资料来源：[housekeeping/classes.py]()。它通过 `__init_subclass__` 与 `__init__` 两个钩子同时监听两种使用方式，并通过类属性（默认 `None`，由子类构造时的关键字参数填充）控制告警行为。

行为规则如下 资料来源：[housekeeping/classes.py]()：

- 仅「直接」继承或实例化会触发警告，孙类继承不会再次触发；
- 自定义消息可同时包含弃用与待弃用两套模板，框架会根据 `warning_cls` 属于哪一类自动选择；
- 通过 `super().__init__()` 调用父类初始化以维持多继承协作。

## ClassMovedMixin — 标记类迁移

`ClassMovedMixin` 适用于「旧类应改为继承新基类」的场景 资料来源：[housekeeping/classes.py]()。与 `ClassDeprecatedMixin` 相比，它额外提供 `new_base_cls` 字段指向新基类（默认取 MRO 中最后一个父类），告警文本会推荐调用方「subclass `<new_subclass>` instead」。

两个 Mixin 内部均通过 `housekeeping.helpers.emit_warning` 统一调用 `warnings.warn`，并自动调整 `stacklevel`，使告警位置指向用户代码而非框架内部 资料来源：[housekeeping/helpers.py]()。

```mermaid
flowchart LR
    A[ClassDeprecatedMixin] -->|init 触发| E[emit_warning]
    A -->|subclass 触发| E
    B[ClassMovedMixin] -->|subclass 触发| E
    E -->|读取 product/version| C[BaseDeprecationWarningMixin]
    E -->|warnings.warn| O((User Code))
```

## 1.1 版本新增能力

Housekeeping 1.1 强化了「过渡期」支持 资料来源：[README.md]()、资料来源：[housekeeping/_version.py]()：

1. **`housekeeping_skip_warning`**：在迁移过程中的新子类上设置 `housekeeping_skip_warning = True`，可抑制重复告警。常见用法是先复制旧基类再用新基类逐步替换，避免新旧路径同时触发警告。
2. **可调用 `warning_cls`**：`warning_cls` 现可传入返回警告类的函数（callable），用于解决循环引用，例如 `lambda: RemovedInMyProject20Warning`。该能力同时适用于 `func_deprecated` / `func_moved` / `module_deprecated` / `module_moved` 等其它工具 资料来源：[housekeeping/modules.py]()、资料来源：[housekeeping/functions.py]()。

## 完整使用示例

```python
from housekeeping import (
    ClassDeprecatedMixin,
    ClassMovedMixin,
    BaseRemovedInWarning,
)

class RemovedInMyProject20Warning(BaseRemovedInWarning):
    product = 'My Project'
    version = '2.0'

# 1) 直接弃用
class OldAPI(ClassDeprecatedMixin,
             warning_cls=RemovedInMyProject20Warning):
    pass

OldAPI()                  # 发出弃用警告
class Child(OldAPI): pass # 发出弃用警告
class Grand(Child): pass  # 不再警告（孙类不再触发）

# 2) 迁移到新基类
class NewAPI: ...

class OldAPICompat(ClassMovedMixin, NewAPI,
                   warning_cls=RemovedInMyProject20Warning,
                   new_base_cls=NewAPI):
    pass
```

## 公共导出与版本

所有类弃用与迁移相关符号都从顶层包统一导出：`ClassDeprecatedMixin`、`ClassMovedMixin` 以及三个警告基类与 `DeprecationWarningType` 类型别名 资料来源：[housekeeping/__init__.py]()。当前 `VERSION` 为 `(1, 2, 0, 'alpha', 0, False)`，可通过 `housekeeping.__version__` 或 `get_version_string()` / `get_package_version()` 读取 资料来源：[housekeeping/_version.py]()、资料来源：[housekeeping/__init__.py]()。

## See Also

- 模块弃用工具：[housekeeping/modules.py]()
- 函数 / 方法弃用工具：[housekeeping/functions.py]()
- 警告基类定义：[housekeeping/base.py]()
- 项目背景与许可证：[README.md:1-15]()

---

<a id='page-7'></a>

## 模块弃用

### 相关页面

相关主题：[基类与弃用警告体系](#page-3), [函数与方法弃用](#page-5)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)
- [housekeeping/__init__.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py)
- [housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)
- [housekeeping/helpers.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)
- [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md)
</details>

# 模块弃用

## 概述与作用

Housekeeping 的"模块弃用"机制由 [`housekeeping/modules.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py) 模块实现，提供两个核心辅助函数：`module_deprecated` 与 `module_moved`。这两者的目标是在 **导入阶段** 即向消费者发出明确的弃用提示，从而让旧模块的使用者可以尽早切换到新位置。

根据 [`housekeeping/__init__.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py) 的导出清单，这两个函数被作为顶层公共 API 直接暴露，调用方无需深入子模块即可使用：

```
'housekeeping/__init__.py': module_deprecated, module_moved
```

依据 [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md) 的描述，模块弃用是整个 Housekeeping 弃用体系（函数、类、参数、字典键、模块）的一部分，建议每个项目先创建项目特定的警告类，再使用这些工具。

## API 详解

[`housekeeping/modules.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py) 中定义的两个函数签名与关键参数如下：

| 函数 | 必填参数 | 关键关键字参数 | 默认行为 |
| --- | --- | --- | --- |
| `module_deprecated` | `warning_cls`、`module_name` | `message=None`、`stacklevel=DEFAULT_STACK_LEVEL` | 模块将被弃用并提示删除版本 |
| `module_moved` | `warning_cls`、`old_module_name`、`new_module_name` | `message=None`、`stacklevel=DEFAULT_STACK_LEVEL` | 提示用户改用 `new_module_name` |

参数说明：

- **`warning_cls`**：可以是警告类本身，也可以是返回该警告类的可调用对象。自 1.1 版本起，调用方可传入函数来避免循环引用（详见 [Release 1.1 说明](https://github.com/beanbaginc/housekeeping/releases/tag/release-1.1)）。
- **`module_name` / `old_module_name`**：通常直接传入 `__name__`，让 Housekeeping 自动识别当前模块名。
- **`new_module_name`**：调用方可使用 `{newmodule}.__name__` 形式引用新模块的字符串名。
- **`message`**：可选的自定义消息，覆盖 Housekeeping 默认模板。
- **`stacklevel`**：默认为 [`housekeeping/base.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py) 中定义的 `DEFAULT_STACK_LEVEL = 2`。函数内部会再 `+1`，以抵消自身栈帧，使警告位置指向上层调用方（通常是导入语句所在文件）。

## 工作流程与数据流

下面的时序图展示了调用 `module_deprecated` 时，从模块导入到警告触发的数据流向：

```mermaid
sequenceDiagram
    participant Importer as 导入方代码
    participant OldMod as 旧模块 (old_module.py)
    participant HK as housekeeping/modules
    participant Helper as housekeeping/helpers
    participant W as warnings 模块

    Importer->>OldMod: import old_module
    activate OldMod
    OldMod->>HK: 调用 module_deprecated(warning_cls, __name__)
    activate HK
    HK->>Helper: emit_warning(warning_cls, msg_template, module_name=..., stacklevel+1)
    activate Helper
    Helper->>Helper: 解析 %(product)s / %(version)s 模板变量
    Helper->>W: warnings.warn(...)
    deactivate Helper
    HK-->>OldMod: 返回 None
    deactivate HK
    OldMod-->>Importer: 模块对象（已发出警告）
    deactivate OldMod
```

关键步骤来自 [`housekeeping/modules.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)：在 `module_deprecated` 与 `module_moved` 中，均使用同一内部助手 [`emit_warning`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)，并显式执行 `stacklevel=stacklevel + 1` 来校正栈深度。

## 使用模式与最佳实践

### 1. 在模块顶部发出弃用警告

旧模块文件 `old_module.py` 应在导入副作用中调用：

```python
from housekeeping import module_deprecated

module_deprecated(RemovedInMyProject20Warning, __name__)
```

该模式要求每个使用方项目先在 `<project_name>.deprecation` 模块中按 [`README.md`](https://github.com/beanbaginc/housekeeping/blob/main/README.md) 中的示例声明 `RemovedInMyProject20Warning` 等版本化类，并继承自 [`housekeeping.base.BaseRemovedInWarning`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)。

### 2. 标记模块已迁移

当模块只是位置变动而非功能变化时，使用 `module_moved`：

```python
from housekeeping import module_moved
from myproject import newmodule

module_moved(RemovedInMyProject20Warning, __name__, newmodule.__name__)
```

默认模板会提示消费者"改用 `new_module_name` 替代"，这与 [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md) 中关于 `ClassMovedMixin` 的指导原则保持一致——区分"已弃用"与"已迁移"两种语义。

### 3. 避免循环引用（自 1.1 起）

若 `warning_cls` 定义在会被 `old_module` 间接导入的模块中，可改传一个返回类的函数：

```python
from housekeeping import module_deprecated

def _my_warning():
    from myproject.deprecation import RemovedInMyProject20Warning
    return RemovedInMyProject20Warning

module_deprecated(_my_warning, __name__)
```

这一能力来自 [Housekeeping 1.1 发布说明](https://github.com/beanbaginc/housekeeping/releases/tag/release-1.1)，与 1.1 中关于"warning_cls 可作为函数"的整体改动保持一致。

## 常见失败模式

1. **警告位置错误**：若未留意 [`housekeeping/modules.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py) 内部的 `stacklevel + 1`，警告来源可能指向 `modules.py` 而非调用方。常见原因是在自定义包装函数中再调用 `module_deprecated` 而未调整 `stacklevel`。
2. **`message` 缺少占位符**：默认模板使用 `%(product)s`、`%(version)s`、`%(module_name)s` 等占位符。如果直接传入纯文本 `message`，将绕过 [`emit_warning`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py) 的格式化逻辑，内容虽然可用，但失去模板一致性。
3. **未设置 `product`/`version`**：若 `warning_cls` 未继承 [`BaseRemovedInWarning`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py) 或未声明 `product`、`version`，发出的警告可能缺失关键上下文。

## See Also

- [函数与参数弃用](函数弃用.md)
- [类弃用与迁移](类弃用.md)
- [Housekeeping README](README.md)

资料来源：[housekeeping/modules.py:1-80](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)、[housekeeping/__init__.py:32-34](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py)、[housekeeping/base.py:21-29](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)、[housekeeping/helpers.py:1-30](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)、[README.md:1-80](https://github.com/beanbaginc/housekeeping/blob/main/README.md)、[Release 1.1](https://github.com/beanbaginc/housekeeping/releases/tag/release-1.1)

---

<a id='page-8'></a>

## 版本、迁移与常见问题

### 相关页面

相关主题：[基类与弃用警告体系](#page-3), [类弃用与迁移](#page-6)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [housekeeping/_version.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/_version.py)
- [housekeeping/__init__.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py)
- [housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py)
- [housekeeping/classes.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py)
- [housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py)
- [housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py)
- [housekeeping/helpers.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/helpers.py)
</details>

# 版本、迁移与常见问题

本页面汇总 Housekeeping 项目的版本元数据、跨版本迁移注意事项，以及使用过程中常见的问题与解决方案，帮助开发者在升级或集成时快速定位关键变更点。

## 版本与发布信息

Housekeeping 当前开发版本的元数据集中维护于 [`housekeeping/_version.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/_version.py) 中。`VERSION` 元组遵循 `(Major, Minor, Micro, tag, release_num, released)` 结构，例如 `(1, 2, 0, 'alpha', 0, False)` 表示 1.2 系列的 alpha 0 预发布版本 资料来源：[housekeeping/_version.py:11-13]()。

项目对外暴露两个版本字符串：

| 函数 | 返回示例 | 用途 |
|------|----------|------|
| `get_version_string()` | `1.2 alpha 0 (dev)` | 显示版本（含 dev 标记） |
| `get_package_version()` | `1.2a0` | 打包（PEP 440）格式 |

资料来源：[housekeeping/_version.py:16-58]()

`__version__` 与 `__version_info__` 在 [`housekeeping/__init__.py`](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/__init__.py) 中被重新导出，便于 `pip show housekeeping` 或 `housekeeping.__version__` 直接读取 资料来源：[housekeeping/__init__.py:30-35]()。

## 1.1 版本迁移要点

社区讨论中频繁提及的 1.1 版本引入了两项非破坏性增强，目的是在迁移旧基类到新基类时抑制不期望的弃用警告。

### `housekeeping_skip_warning` 类属性

`ClassDeprecatedMixin` 与 `ClassMovedMixin` 在被继承链上的子类再次继承时，可通过设置 `housekeeping_skip_warning = True` 跳过警告。常见场景为：当新基类把旧基类作为混入时，旧基类的 `__init_subclass__` 不应再重复提示 资料来源：[housekeeping/classes.py:130-210]()。

```python
class NewBase(ClassDeprecatedMixin, OldDeprecatedBase,
              warning_cls=RemovedInMyProject20Warning):
    housekeeping_skip_warning = True
```

### 警告类作为可调用对象

1.1 之后，所有接收 `warning_cls` 参数的 API（`module_deprecated`、`module_moved`、`func_deprecated`、`func_moved`、`deprecated_arg_value`、`deprecate_non_keyword_only_args` 以及两个 Class 混入）均允许传入"返回警告类的函数"，用于规避循环引用 资料来源：[housekeeping/functions.py:48-58](), [housekeeping/modules.py:18-26](), [housekeeping/classes.py:80-92]()。

```python
from housekeeping import func_deprecated

def _warning_cls():
    from myproject.deprecation import RemovedInMyProject20Warning
    return RemovedInMyProject20Warning

@func_deprecated(_warning_cls)
def old_api():
    ...
```

## 常见问题与排查

### 警告栈帧指向 Housekeeping 内部

`emit_warning` 默认 `DEFAULT_STACK_LEVEL = 2`，各 helper 会在此基础上 `+1` 以跳入调用方栈帧。若仍看到 `housekeeping/helpers.py`，说明调用方未正确传递 `stacklevel` 或在包装器中再次封装 资料来源：[housekeeping/base.py:30-33](), [housekeeping/helpers.py:60-90]()。

### 子类被重复告警

只有"直接子类化"才会触发 `__init_subclass__` 中的告警；孙子类不会。若期望继承链每一层都告警，需要在中间类显式设置 `housekeeping_skip_warning = False` 资料来源：[housekeeping/classes.py:130-210]()。

### 循环导入导致类未定义

`warning_cls` 接受可调用对象正是为此场景设计：把导入逻辑放进函数体，延迟到首次调用时再解析模块 资料来源：[housekeeping/functions.py:50-58]()。

### 旧 API 的 `message` 覆盖

所有 helper 都支持 `message` 关键字参数；若同时提供 `message` 与 `new_name`，自定义消息会完全覆盖模板字符串，模板变量（如 `%(func_name)s`）将不再被填充 资料来源：[housekeeping/functions.py:75-90](), [housekeeping/modules.py:45-52]()。

### 自定义显示名

`format_display_name` 会优先使用 `__qualname__`，因此嵌套函数或方法的告警信息包含类名前缀，便于消费者定位 资料来源：[housekeeping/helpers.py:60-90]()。

## 升级检查清单

在升级到 1.1 及以上版本时，建议按以下顺序核查：

1. 确认所有 `warning_cls=` 实参仍传入的是类对象（向后兼容）或改为可调用对象以打破循环。
2. 检查新基类是否同时继承旧弃用类；若是，设置 `housekeeping_skip_warning = True`。
3. 通过 `housekeeping.get_version_string()` 在运行时输出版本，便于排错时核对。
4. 若自定义 `message`，确认不再依赖 `%(...)s` 模板变量。

## See Also

- [README.md](https://github.com/beanbaginc/housekeeping/blob/main/README.md) — 项目概览与安装指引
- [housekeeping/base.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/base.py) — 基类与类型别名定义
- [housekeeping/classes.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/classes.py) — 类弃用与迁移混入
- [housekeeping/functions.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/functions.py) — 函数/方法弃用装饰器
- [housekeeping/modules.py](https://github.com/beanbaginc/housekeeping/blob/main/housekeeping/modules.py) — 模块弃用工具

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：beanbaginc/housekeeping

摘要：发现 6 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。

## 1. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 证据：capability.assumptions | github_repo:636447359 | https://github.com/beanbaginc/housekeeping | README/documentation is current enough for a first validation pass.

## 2. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 证据：evidence.maintainer_signals | github_repo:636447359 | https://github.com/beanbaginc/housekeeping | last_activity_observed missing

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 证据：downstream_validation.risk_items | github_repo:636447359 | https://github.com/beanbaginc/housekeeping | no_demo; severity=medium

## 4. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 证据：risks.scoring_risks | github_repo:636447359 | https://github.com/beanbaginc/housekeeping | no_demo; severity=medium

## 5. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 证据：evidence.maintainer_signals | github_repo:636447359 | https://github.com/beanbaginc/housekeeping | issue_or_pr_quality=unknown

## 6. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 证据：evidence.maintainer_signals | github_repo:636447359 | https://github.com/beanbaginc/housekeeping | release_recency=unknown

<!-- canonical_name: beanbaginc/housekeeping; human_manual_source: deepwiki_human_wiki -->
