Skip to content

Conversation

@pizeroLOL
Copy link
Owner

@pizeroLOL pizeroLOL commented Oct 31, 2025

Sourcery 总结

重构并增强 CSES 库的 API,以提高可用性、序列化和类型验证能力

新功能:

  • 添加工厂方法 CSES.from_str 和 CSES.from_file,用于构建日程对象
  • 实现 CSES.to_yaml 和 CSES.to_file,用于 YAML 序列化和文件输出
  • 提供 eq 方法,通过内容比较 CSES 实例

改进:

  • 在 utils 模块中引入日志设置和 repr 工具,并为 datetime.time 添加自定义 YAML 表示器
  • 为 Lesson 的时间字段添加 ensure_time 验证器和序列化器,并将 Lesson.subject 替换为字符串引用
  • 将日程周的 WeekType 枚举替换为 Literal 类型,并将 CSES.schedule 重命名为 CSES.schedules,使用基于字典的主题
  • 使 Subject 字段变为可选,并更新结构以使用 Pydantic 验证器
  • 提供 NoAliasDumper 以禁用 YAML 锚点并改进转储格式

文档:

  • 更新文档字符串,以反映新的工厂方法、方法名称和类型更改

杂项:

  • 同步示例 YAML,以包含新的日程示例
Original summary in English

Summary by Sourcery

Refactor and enhance the CSES library API to improve usability, serialization, and type validation

New Features:

  • Add factory methods CSES.from_str and CSES.from_file for constructing schedule objects
  • Implement CSES.to_yaml and CSES.to_file for YAML serialization and file output
  • Provide eq method to compare CSES instances by content

Enhancements:

  • Introduce logging setup and repr utilities in utils module and add custom YAML representer for datetime.time
  • Add ensure_time validator and serializers for Lesson time fields and replace Lesson.subject with string reference
  • Replace WeekType enum with Literal types for schedule weeks and rename CSES.schedule to CSES.schedules with dict-based subjects
  • Make Subject fields optional and update structures to use Pydantic validators
  • Provide NoAliasDumper to disable YAML anchors and improve dump formatting

Documentation:

  • Update docstrings to reflect new factory methods, method names, and type changes

Chores:

  • Sync example YAML to include new schedule example

@pizeroLOL pizeroLOL merged commit 109c759 into pizeroLOL:cseslib4py Oct 31, 2025
1 check was pending
@sourcery-ai
Copy link

sourcery-ai bot commented Oct 31, 2025

审阅者指南

此 PR 重构了核心 CSES API,以使用工厂方法进行加载和序列化,通过时间转换和 YAML 钩子增强了内部实用工具,将数据模型现代化为使用原始类型和验证器而非自定义枚举,并更新了示例和错误模块以保持一致性。

重构后的 CSES 核心 API 和模型类图

classDiagram
    class CSES {
        +int version
        +dict subjects
        +Schedule schedules
        +CSES()
        +from_str(str content) CSES
        +from_file(str fp) CSES
        +to_yaml() str
        +to_file(str fp, str mode)
        +_gen_dict() dict
        +__eq__(other)
    }
    class Subject {
        +str name
        +Optional[str] simplified_name
        +Optional[str] teacher
        +Optional[str] room
    }
    class Lesson {
        +str subject
        +datetime.time start_time
        +datetime.time end_time
        +serialize_time(time: datetime.time) str
    }
    class SingleDaySchedule {
        +Literal[1,2,3,4,5,6,7] enable_day
        +list~Lesson~ classes
        +str name
        +Literal['all','odd','even'] weeks
        +is_enabled_on_week(int week) bool
        +is_enabled_on_day(datetime.date start_day, datetime.date day) bool
    }
    class Schedule {
        +list~SingleDaySchedule~ data
    }
    CSES --> Schedule : schedules
    CSES --> Subject : subjects
    Schedule --> SingleDaySchedule
    SingleDaySchedule --> Lesson
    Lesson --> Subject : subject (by name)
Loading

新的实用函数和日志记录器类图

classDiagram
    class utils {
        +week_num(datetime.date, datetime.date) int
        +ensure_time(str|int|datetime.time) datetime.time
        +serialize_time(dumper, datetime.time) yaml.nodes.ScalarNode
        +NoAliasDumper
        +log
        +repr_
    }
    class NoAliasDumper {
        +ignore_aliases(data)
        +increase_indent(flow, indentless)
    }
    utils --> NoAliasDumper
Loading

文件级变更

变更 详情 文件
将 CSES 类重构为基于工厂的 API,并添加带日志的序列化/I/O
  • init 转换为无参数初始化器并弃用直接构造函数
  • 添加 from_str 和 from_file 类方法用于加载日程
  • 实现 to_yaml、to_file、_gen_dict 和 eq 方法
  • 为 datetime.time 集成 yaml.add_representer 并添加模块级日志调用
cses/__init__.py
增强 utils 模块,支持日志记录器、repr、时间处理和 YAML 转储
  • 在模块导入时配置日志记录和 repr_ 限制器
  • 实现 ensure_time 用于带正则表达式的字符串/整数/时间转换
  • 定义 serialize_time 钩子和 NoAliasDumper 以禁用 YAML 别名
cses/utils.py
简化数据模型,并用 Literals 和验证器替换 WeekType 枚举
  • 默认使 Subject 字段可选
  • 更改 Lesson 以接受主题名称,并使用 BeforeValidator 进行时间转换
  • 添加 field_serializer 以格式化时间,移除 WeekType 枚举
  • 在日程中使用 Literal 类型表示 enable_day 和 weeks
cses/structures.py
更新示例 YAML 并清理错误模块
  • 向示例 YAML 添加新的日程条目
  • 修复 cses/errors.py 中的格式和尾随行问题
cses_example.yaml
cses/errors.py

提示和命令

与 Sourcery 交互

  • 触发新审阅: 在拉取请求上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审阅评论。
  • 从审阅评论生成 GitHub issue: 通过回复审阅评论,要求 Sourcery 从中创建一个 issue。你也可以回复审阅评论并带上 @sourcery-ai issue 来创建一个 issue。
  • 生成拉取请求标题: 随时在拉取请求标题的任何位置写入 @sourcery-ai 以生成标题。你也可以在拉取请求上评论 @sourcery-ai title 以随时(重新)生成标题。
  • 生成拉取请求摘要: 随时在拉取请求正文的任何位置写入 @sourcery-ai summary,在你想要的位置生成 PR 摘要。你也可以在拉取请求上评论 @sourcery-ai summary 以随时(重新)生成摘要。
  • 生成审阅者指南: 在拉取请求上评论 @sourcery-ai guide 以随时(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在拉取请求上评论 @sourcery-ai resolve 以解决所有 Sourcery 评论。如果你已经处理了所有评论并且不想再看到它们,这会很有用。
  • 驳回所有 Sourcery 审阅: 在拉取请求上评论 @sourcery-ai dismiss 以驳回所有现有 Sourcery 审阅。如果你想从头开始进行新的审阅,这尤其有用——别忘了评论 @sourcery-ai review 来触发新的审阅!

自定义你的体验

访问你的仪表盘以:

  • 启用或禁用审阅功能,例如 Sourcery 生成的拉取请求摘要、审阅者指南等。
  • 更改审阅语言。
  • 添加、删除或编辑自定义审阅说明。
  • 调整其他审阅设置。

获取帮助

Original review guide in English

Reviewer's Guide

This PR refactors the core CSES API to use factory methods for loading and serialization, enhances internal utilities with time conversion and YAML hooks, modernizes data models to use primitive types and validators instead of custom enums, and updates example and error modules for consistency.

Class diagram for refactored CSES core API and models

classDiagram
    class CSES {
        +int version
        +dict subjects
        +Schedule schedules
        +CSES()
        +from_str(str content) CSES
        +from_file(str fp) CSES
        +to_yaml() str
        +to_file(str fp, str mode)
        +_gen_dict() dict
        +__eq__(other)
    }
    class Subject {
        +str name
        +Optional[str] simplified_name
        +Optional[str] teacher
        +Optional[str] room
    }
    class Lesson {
        +str subject
        +datetime.time start_time
        +datetime.time end_time
        +serialize_time(time: datetime.time) str
    }
    class SingleDaySchedule {
        +Literal[1,2,3,4,5,6,7] enable_day
        +list~Lesson~ classes
        +str name
        +Literal['all','odd','even'] weeks
        +is_enabled_on_week(int week) bool
        +is_enabled_on_day(datetime.date start_day, datetime.date day) bool
    }
    class Schedule {
        +list~SingleDaySchedule~ data
    }
    CSES --> Schedule : schedules
    CSES --> Subject : subjects
    Schedule --> SingleDaySchedule
    SingleDaySchedule --> Lesson
    Lesson --> Subject : subject (by name)
Loading

Class diagram for new utility functions and logger

classDiagram
    class utils {
        +week_num(datetime.date, datetime.date) int
        +ensure_time(str|int|datetime.time) datetime.time
        +serialize_time(dumper, datetime.time) yaml.nodes.ScalarNode
        +NoAliasDumper
        +log
        +repr_
    }
    class NoAliasDumper {
        +ignore_aliases(data)
        +increase_indent(flow, indentless)
    }
    utils --> NoAliasDumper
Loading

File-Level Changes

Change Details Files
Refactor CSES class into factory-based API and add serialization/I/O with logging
  • Convert init to no-arg initializer and deprecate direct constructor
  • Add from_str and from_file class methods for loading schedules
  • Implement to_yaml, to_file, _gen_dict and eq methods
  • Integrate yaml.add_representer for datetime.time and add module-level log calls
cses/__init__.py
Enhance utils with logger, repr, time handling and YAML dump support
  • Configure logging and repr_ limiter at module import
  • Implement ensure_time for string/int/time conversion with regex
  • Define serialize_time hook and NoAliasDumper to disable YAML aliases
cses/utils.py
Simplify data models and replace WeekType enum with Literals and validators
  • Make Subject fields optional by default
  • Change Lesson to accept subject name and use BeforeValidator for time conversion
  • Add field_serializer to format times, remove WeekType enum
  • Use Literal types for enable_day and weeks in schedules
cses/structures.py
Update example YAML and clean up error module
  • Add a new schedule entry to example YAML
  • Fix formatting and trailing line issues in cses/errors.py
cses_example.yaml
cses/errors.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

大家好 - 我已经审阅了你的更改 - 以下是一些反馈:

  • 避免在库内部(utils.py)通过 basicConfig 配置根记录器 — 日志设置应留给导入此模块的应用程序。
  • __init__.py 中对 yaml.add_representerlog.info 的调用在导入时引入了副作用;考虑将这些推迟到一个显式的初始化函数或类方法中,以防止全局状态污染。
  • 放弃 WeekType 枚举而改用字符串字面量简化了模型,但牺牲了类型安全性和可发现性 — 考虑保留枚举或为允许值添加更严格的验证。
给AI代理的提示
请处理此代码审查中的评论:

## 总体评论
- 避免在库内部(utils.py)通过 basicConfig 配置根记录器 — 日志设置应留给导入此模块的应用程序。
- `__init__.py` 中对 `yaml.add_representer``log.info` 的调用在导入时引入了副作用;考虑将这些推迟到一个显式的初始化函数或类方法中,以防止全局状态污染。
- 放弃 `WeekType` 枚举而改用字符串字面量简化了模型,但牺牲了类型安全性和可发现性 — 考虑保留枚举或为允许值添加更严格的验证。

## 单个评论

### 评论 1
<location> `cses/__init__.py:139` </location>
<code_context>
+            fp (str): 要写入的文件路径。
+            mode (str, optional): 写入模式,默认值为 ``'w'`` ,即覆盖写入。
+        """
+        os.makedirs(os.path.dirname(fp), exist_ok=True)
+        with open(fp, mode, encoding='utf8') as f:
+            f.write(self.to_yaml())
</code_context>

<issue_to_address>
**issue:** 如果 fp 是一个没有目录的文件名,os.makedirs 可能会失败。

在调用 os.makedirs 之前检查 os.path.dirname(fp) 是否非空,以避免当 fp 只是一个文件名时出现错误。
</issue_to_address>

### 评论 2
<location> `cses/utils.py:12` </location>
<code_context>
+
+import yaml
+
+logging.basicConfig(level=logging.DEBUG,
+                    format="[{asctime} - {module}.{funcName}:{lineno}] \t{levelname}:\t {message}",
+                    style="{",
</code_context>

<issue_to_address>
**issue (complexity):** 考虑通过将记录器和 repr 设置推迟到运行时且仅在需要时进行,来消除导入时的副作用。

```suggestion
# 1) 移除全局 basicConfig 副作用,并将记录器设置移至应用程序的入口点
#    (例如,在 CLI 或主模块的 `if __name__ == "__main__":` 下)。

--- a/your_module.py
@@
- import logging
- from sys import stderr
-
- logging.basicConfig(
-     level=logging.DEBUG,
-     format="[{asctime} - {module}.{funcName}:{lineno}] \t{levelname}:\t {message}",
-     style="{",
-     stream=stderr,
- )
- log = logging.getLogger(__name__)
- log.info(f"Loaded logger: {log!r}")
+ import logging
+
+ # library code should not call basicConfig() at import time.
+ log = logging.getLogger(__name__)
```

```suggestion
# 2) 仅在实际需要时才延迟初始化自定义 repr,以避免导入时膨胀。

--- a/your_module.py
@@
- import reprlib
-
- repr_ = reprlib.Repr(
-     maxlevel=3, maxtuple=3, maxlist=3, maxarray=3, maxdict=3, maxset=3,
-     maxfrozenset=3, maxdeque=3, maxstring=30, maxlong=50, maxother=30,
-     fillvalue=' ... ', indent=None
- ).repr
+ import reprlib
+
+ _repr_instance = None
+ def get_repr():
+     global _repr_instance
+     if _repr_instance is None:
+         _repr_instance = reprlib.Repr(
+             maxlevel=3, maxtuple=3, maxlist=3, maxarray=3, maxdict=3,
+             maxset=3, maxfrozenset=3, maxdeque=3, maxstring=30,
+             maxlong=50, maxother=30, fillvalue=' ... ', indent=None
+         ).repr
+     return _repr_instance
```

# 其他地方的使用:
```python
# old:
#   log.debug(repr_(some_obj))
# new:
   log.debug(get_repr()(some_obj))
```
这些更改消除了导入时的副作用,并将昂贵的设置推迟到实际使用时进行,而不会改变现有行为。
</issue_to_address>

### 评论 3
<location> `cses/utils.py:44-45` </location>
<code_context>
def week_num(start_day: datetime.date, day: datetime.date) -> int:
    """
    计算指定日期是从开始日期开始的第多少周。

    Args:
        day (datetime.date): 要计算周次的日期
        start_day (datetime.date): 课程开始的日期,用于计算周次

    Returns:
        int: 指定日期是从开始日期开始的第多少周

    Examples:
        >>> week_num(datetime.date(2025, 9, 1), datetime.date(2025, 9, 4))
        1
        >>> week_num(datetime.date(2025, 9, 1), datetime.date(2025, 9, 16))
        3
        >>> week_num(datetime.date(2025, 9, 1), datetime.date(2025, 10, 24))
        8
    """
    res = (day - start_day).days // 7 + 1
    return res

</code_context>

<issue_to_address>
**suggestion (code-quality):** 内联立即返回的变量 ([`inline-immediately-returned-variable`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/inline-immediately-returned-variable/))

```suggestion
    return (day - start_day).days // 7 + 1
```
</issue_to_address>

Sourcery 对开源项目免费 - 如果你喜欢我们的评论,请考虑分享它们 ✨
帮助我更有用!请点击每个评论的 👍 或 👎,我将利用这些反馈来改进你的评论。
Original comment in English

Hey there - I've reviewed your changes - here's some feedback:

  • Avoid configuring the root logger via basicConfig inside the library (utils.py) — logging setup should be left to the application importing this module.
  • The calls to yaml.add_representer and log.info in init.py introduce side effects at import time; consider deferring these to an explicit init function or classmethod to prevent global state pollution.
  • Dropping the WeekType enum in favor of string literals simplifies the model but sacrifices type safety and discoverability—consider retaining an enum or adding stricter validation for allowed values.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Avoid configuring the root logger via basicConfig inside the library (utils.py) — logging setup should be left to the application importing this module.
- The calls to yaml.add_representer and log.info in __init__.py introduce side effects at import time; consider deferring these to an explicit init function or classmethod to prevent global state pollution.
- Dropping the WeekType enum in favor of string literals simplifies the model but sacrifices type safety and discoverability—consider retaining an enum or adding stricter validation for allowed values.

## Individual Comments

### Comment 1
<location> `cses/__init__.py:139` </location>
<code_context>
+            fp (str): 要写入的文件路径。
+            mode (str, optional): 写入模式,默认值为 ``'w'`` ,即覆盖写入。
+        """
+        os.makedirs(os.path.dirname(fp), exist_ok=True)
+        with open(fp, mode, encoding='utf8') as f:
+            f.write(self.to_yaml())
</code_context>

<issue_to_address>
**issue:** os.makedirs may fail if fp is a filename without a directory.

Check if os.path.dirname(fp) is non-empty before calling os.makedirs to avoid errors when fp is just a filename.
</issue_to_address>

### Comment 2
<location> `cses/utils.py:12` </location>
<code_context>
+
+import yaml
+
+logging.basicConfig(level=logging.DEBUG,
+                    format="[{asctime} - {module}.{funcName}:{lineno}] \t{levelname}:\t {message}",
+                    style="{",
</code_context>

<issue_to_address>
**issue (complexity):** Consider removing import-time side effects by deferring logger and repr setup to runtime and only when needed.

```suggestion
# 1) Remove global basicConfig side‐effect and move logger setup to your application's entry point
#    (e.g. under `if __name__ == "__main__":` in your CLI or main module).

--- a/your_module.py
@@
- import logging
- from sys import stderr
-
- logging.basicConfig(
-     level=logging.DEBUG,
-     format="[{asctime} - {module}.{funcName}:{lineno}] \t{levelname}:\t {message}",
-     style="{",
-     stream=stderr,
- )
- log = logging.getLogger(__name__)
- log.info(f"Loaded logger: {log!r}")
+ import logging
+
+ # library code should not call basicConfig() at import time.
+ log = logging.getLogger(__name__)
```

```suggestion
# 2) Lazy‐initialize the custom repr only when actually needed to avoid import-time bloat.

--- a/your_module.py
@@
- import reprlib
-
- repr_ = reprlib.Repr(
-     maxlevel=3, maxtuple=3, maxlist=3, maxarray=3, maxdict=3, maxset=3,
-     maxfrozenset=3, maxdeque=3, maxstring=30, maxlong=50, maxother=30,
-     fillvalue=' ... ', indent=None
- ).repr
+ import reprlib
+
+ _repr_instance = None
+ def get_repr():
+     global _repr_instance
+     if _repr_instance is None:
+         _repr_instance = reprlib.Repr(
+             maxlevel=3, maxtuple=3, maxlist=3, maxarray=3, maxdict=3,
+             maxset=3, maxfrozenset=3, maxdeque=3, maxstring=30,
+             maxlong=50, maxother=30, fillvalue=' ... ', indent=None
+         ).repr
+     return _repr_instance
```

# Usage elsewhere:
```python
# old:
#   log.debug(repr_(some_obj))
# new:
   log.debug(get_repr()(some_obj))
```
These changes remove import‐time side effects and defer expensive setup until actually used, without altering existing behavior.
</issue_to_address>

### Comment 3
<location> `cses/utils.py:44-45` </location>
<code_context>
def week_num(start_day: datetime.date, day: datetime.date) -> int:
    """
    计算指定日期是从开始日期开始的第多少周。

    Args:
        day (datetime.date): 要计算周次的日期
        start_day (datetime.date): 课程开始的日期,用于计算周次

    Returns:
        int: 指定日期是从开始日期开始的第多少周

    Examples:
        >>> week_num(datetime.date(2025, 9, 1), datetime.date(2025, 9, 4))
        1
        >>> week_num(datetime.date(2025, 9, 1), datetime.date(2025, 9, 16))
        3
        >>> week_num(datetime.date(2025, 9, 1), datetime.date(2025, 10, 24))
        8
    """
    res = (day - start_day).days // 7 + 1
    return res

</code_context>

<issue_to_address>
**suggestion (code-quality):** Inline variable that is immediately returned ([`inline-immediately-returned-variable`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/inline-immediately-returned-variable/))

```suggestion
    return (day - start_day).days // 7 + 1
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

fp (str): 要写入的文件路径。
mode (str, optional): 写入模式,默认值为 ``'w'`` ,即覆盖写入。
"""
os.makedirs(os.path.dirname(fp), exist_ok=True)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: 如果 fp 是一个没有目录的文件名,os.makedirs 可能会失败。

在调用 os.makedirs 之前检查 os.path.dirname(fp) 是否非空,以避免当 fp 只是一个文件名时出现错误。

Original comment in English

issue: os.makedirs may fail if fp is a filename without a directory.

Check if os.path.dirname(fp) is non-empty before calling os.makedirs to avoid errors when fp is just a filename.


import yaml

logging.basicConfig(level=logging.DEBUG,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): 考虑通过将记录器和 repr 设置推迟到运行时且仅在需要时进行,来消除导入时的副作用。

Suggested change
logging.basicConfig(level=logging.DEBUG,
# 1) 移除全局 basicConfig 副作用,并将记录器设置移至应用程序的入口点
# (例如,在 CLI 或主模块的 `if __name__ == "__main__":` 下)。
--- a/your_module.py
@@
- import logging
- from sys import stderr
-
- logging.basicConfig(
- level=logging.DEBUG,
- format="[{asctime} - {module}.{funcName}:{lineno}] \t{levelname}:\t {message}",
- style="{",
- stream=stderr,
- )
- log = logging.getLogger(__name__)
- log.info(f"Loaded logger: {log!r}")
+ import logging
+
+ # library code should not call basicConfig() at import time.
+ log = logging.getLogger(__name__)
Suggested change
logging.basicConfig(level=logging.DEBUG,
# 2) 仅在实际需要时才延迟初始化自定义 repr,以避免导入时膨胀。
--- a/your_module.py
@@
- import reprlib
-
- repr_ = reprlib.Repr(
- maxlevel=3, maxtuple=3, maxlist=3, maxarray=3, maxdict=3, maxset=3,
- maxfrozenset=3, maxdeque=3, maxstring=30, maxlong=50, maxother=30,
- fillvalue=' ... ', indent=None
- ).repr
+ import reprlib
+
+ _repr_instance = None
+ def get_repr():
+ global _repr_instance
+ if _repr_instance is None:
+ _repr_instance = reprlib.Repr(
+ maxlevel=3, maxtuple=3, maxlist=3, maxarray=3, maxdict=3,
+ maxset=3, maxfrozenset=3, maxdeque=3, maxstring=30,
+ maxlong=50, maxother=30, fillvalue=' ... ', indent=None
+ ).repr
+ return _repr_instance

其他地方的使用:

# old:
#   log.debug(repr_(some_obj))
# new:
   log.debug(get_repr()(some_obj))

这些更改消除了导入时的副作用,并将昂贵的设置推迟到实际使用时进行,而不会改变现有行为。

Original comment in English

issue (complexity): Consider removing import-time side effects by deferring logger and repr setup to runtime and only when needed.

Suggested change
logging.basicConfig(level=logging.DEBUG,
# 1) Remove global basicConfig side‐effect and move logger setup to your application's entry point
# (e.g. under `if __name__ == "__main__":` in your CLI or main module).
--- a/your_module.py
@@
- import logging
- from sys import stderr
-
- logging.basicConfig(
- level=logging.DEBUG,
- format="[{asctime} - {module}.{funcName}:{lineno}] \t{levelname}:\t {message}",
- style="{",
- stream=stderr,
- )
- log = logging.getLogger(__name__)
- log.info(f"Loaded logger: {log!r}")
+ import logging
+
+ # library code should not call basicConfig() at import time.
+ log = logging.getLogger(__name__)
Suggested change
logging.basicConfig(level=logging.DEBUG,
# 2) Lazy‐initialize the custom repr only when actually needed to avoid import-time bloat.
--- a/your_module.py
@@
- import reprlib
-
- repr_ = reprlib.Repr(
- maxlevel=3, maxtuple=3, maxlist=3, maxarray=3, maxdict=3, maxset=3,
- maxfrozenset=3, maxdeque=3, maxstring=30, maxlong=50, maxother=30,
- fillvalue=' ... ', indent=None
- ).repr
+ import reprlib
+
+ _repr_instance = None
+ def get_repr():
+ global _repr_instance
+ if _repr_instance is None:
+ _repr_instance = reprlib.Repr(
+ maxlevel=3, maxtuple=3, maxlist=3, maxarray=3, maxdict=3,
+ maxset=3, maxfrozenset=3, maxdeque=3, maxstring=30,
+ maxlong=50, maxother=30, fillvalue=' ... ', indent=None
+ ).repr
+ return _repr_instance

Usage elsewhere:

# old:
#   log.debug(repr_(some_obj))
# new:
   log.debug(get_repr()(some_obj))

These changes remove import‐time side effects and defer expensive setup until actually used, without altering existing behavior.

Comment on lines +44 to +45
res = (day - start_day).days // 7 + 1
return res
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): 内联立即返回的变量 (inline-immediately-returned-variable)

Suggested change
res = (day - start_day).days // 7 + 1
return res
return (day - start_day).days // 7 + 1
Original comment in English

suggestion (code-quality): Inline variable that is immediately returned (inline-immediately-returned-variable)

Suggested change
res = (day - start_day).days // 7 + 1
return res
return (day - start_day).days // 7 + 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants