Skip to content

Conversation

LinZhihao-723
Copy link
Member

@LinZhihao-723 LinZhihao-723 commented Feb 17, 2025

Description

As title.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

  • Ensure the example code works.

Summary by CodeRabbit

  • Documentation
    • Introduced a new section titled "Logging handlers" in the README.md.
    • Detailed information on the ClpKeyValuePairStreamHandler class and its usage for logging structured key-value pairs.
    • Specified requirements for key-value formats and provided an example code snippet.
    • Added a subsection on reading kv-pair IR streams, including deserialization options and relevant documentation links.

Copy link

coderabbitai bot commented Feb 17, 2025

Walkthrough

The pull request introduces a new section in the README.md titled "Logging handlers," which details the ClpKeyValuePairStreamHandler class. This section outlines the requirements for key-value pairs, differentiates between user-generated and auto-generated kv-pairs, and provides an example of how to use the handler. It clarifies that the handler does not support string formatting of log events and notes the absence of the CLPLogLevelTimeout feature, which is planned for future updates.

Changes

File Change Summary
README.md Added a new section titled "Logging handlers" detailing the ClpKeyValuePairStreamHandler, its functionality, key-value pair requirements, and instructions for reading kv-pair IR streams.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant Logger as Logger
    participant Handler as ClpKeyValuePairStreamHandler
    participant Stream as CLP IR Stream

    App->>Logger: Log message with key-value dictionary
    Logger->>Handler: Forward log record (with key-value data)
    Handler->>Handler: Serialize key-value pairs into CLP format
    Handler->>Stream: Write the serialized data
Loading

Possibly related PRs


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

README.md Outdated
Comment on lines 36 to 63
Introduced in version 0.0.14, `ClpKeyValuePairStreamHandler` enables applications to log and
serialize key-value pair objects directly into the CLP key-value pair IR stream format using
Python's standard logging APIs. It operates similarly to Python's standard `logging.StreamHandler`,
with the following differences:
- Log events (`logging.LogRecord`) should contain the key-value pairs that a user wants to log
as a Python dictionary.
- These key-value pairs are written directly, without being formatted as a string.
- The key-value pairs will be serialized into the CLP key-value pair IR format before writing to
the stream.

> [!NOTE]
> The current `ClpKeyValuePairStreamHandler` does not support `CLPLogLevelTimeout`. This feature
> will be added in a future release.
### Key-value pairs as Python dictionary

Key-value pairs in the log event, presented as Python dictionaries, must abide by the following
rules:

- Keys must be of type `str`.
- Values must be one of the following types:
- Primitives: `int`, `float`, `str`, `bool`, or `None`.
- Arrays (`list`), where each array:
- may contain primitive values, dictionaries, or nested arrays.
- can be empty.
- Dictionaries (`dict`), where each dictionary:
- must adhere to the aforementioned rules for keys and values.
- can be empty.
Copy link
Member Author

Choose a reason for hiding this comment

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

Some parts are directly copied from ClpKeyValuePairStreamHandler's docstring.

README.md Outdated
- [clp-ffi-py][clp-ffi-py-pypi]: This library provides [Deserializer][clp-ffi-py-deserializer-doc]
to access a kv-pair IR stream in Python. See [this example][clp-ffi-py-deserializer-example] for
usage details.
- clp-ffi-js: TODO
Copy link
Member Author

Choose a reason for hiding this comment

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

Do we want to mention log-viewer here?

README.md Outdated
to access a kv-pair IR stream in Python. See [this example][clp-ffi-py-deserializer-example] for
usage details.
- clp-ffi-js: TODO

Copy link
Member Author

Choose a reason for hiding this comment

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

We could also add a sentence to say the generated IR stream can be directly ingested into clp-s.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
README.md (3)

50-64: Enhance Readability in Bullet Points
Some bullet points (e.g. on lines 60 and 63) use phrases like "can be empty" without a subject, which affects the clarity of the instructions. Consider rephrasing these lines to form complete sentences (e.g. "Arrays can be empty." and "Dictionaries can be empty.") to improve readability and compliance with style guidelines.

🧰 Tools
🪛 LanguageTool

[style] ~60-~60: To form a complete sentence, be sure to include a subject.
Context: ..., dictionaries, or nested arrays. - can be empty. - Dictionaries (dict), wh...

(MISSING_IT_THERE)


[style] ~63-~63: To form a complete sentence, be sure to include a subject.
Context: ...tioned rules for keys and values. - can be empty. ### Auto-generated kv-pairs ...

(MISSING_IT_THERE)


65-85: Clarify Auto-generated vs. User-generated kv-pairs Description
While the section successfully delineates auto-generated from user-generated key-value pairs, the description for properties like "unix_millisecs" (line 74) could be refined. For example, consider rephrasing "Unix timestamp in milliseconds since epoch" to "The Unix timestamp (in milliseconds since the epoch)" to align with grammatical expectations.

🧰 Tools
🪛 LanguageTool

[grammar] ~74-~74: The singular proper name ‘Unix’ must be used with a third-person or a past tense verb.
Context: ...): - "unix_millisecs" (int): Unix timestamp in milliseconds since epoch. - "utc...

(HE_VERB_AGR)


107-115: Overview of IR Stream Reading Options
This section concisely summarises the available options for reading and deserialising kv-pair IR streams. For further clarity, consider adding an example snippet in future updates to illustrate the deserialization process in practice.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0359ef6 and 9ece534.

📒 Files selected for processing (1)
  • README.md (2 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md

[style] ~60-~60: To form a complete sentence, be sure to include a subject.
Context: ..., dictionaries, or nested arrays. - can be empty. - Dictionaries (dict), wh...

(MISSING_IT_THERE)


[style] ~63-~63: To form a complete sentence, be sure to include a subject.
Context: ...tioned rules for keys and values. - can be empty. ### Auto-generated kv-pairs ...

(MISSING_IT_THERE)


[grammar] ~74-~74: The singular proper name ‘Unix’ must be used with a third-person or a past tense verb.
Context: ...): - "unix_millisecs" (int): Unix timestamp in milliseconds since epoch. - "utc...

(HE_VERB_AGR)

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: test (ubuntu-latest, 3.11)
  • GitHub Check: test (macos-latest, 3.11)
  • GitHub Check: test (macos-latest, 3.8)
  • GitHub Check: test-python37 (ubuntu-22.04, 3.7)
  • GitHub Check: test-python37 (macos-13, 3.7)
🔇 Additional comments (3)
README.md (3)

34-49: Clear Introduction to ClpKeyValuePairStreamHandler Documentation
The new section clearly outlines the purpose and operational differences of the ClpKeyValuePairStreamHandler relative to Python’s standard logging handlers. This addition provides a solid overview for users on how key-value pairs are logged and serialized into the CLP IR stream format.


87-105: Well-Formatted and Clear Example Code
The provided example code snippet succinctly demonstrates how to use the ClpKeyValuePairStreamHandler. It is well-structured and adheres to best practices, making it easy for users to follow.


353-356: Accuracy and Maintenance of Link References
The newly added link references for [clp-ffi-py-deserializer-doc], [clp-ffi-py-deserializer-example], and [clp-ffi-py-kv-pair-ir-stream] are correctly formatted and enhance the documentation. Ensure that these links remain up-to-date with external documentation to maintain accuracy over time.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
README.md (4)

46-52: Effective Use of Blockquotes for Notes and Warnings

The blockquotes clearly differentiate the note about the lack of support for setting a Formatter and the warning regarding the current absence of the CLPLogLevelTimeout feature. To better adhere to markdownlint standards, check that there are no unintended blank lines inside these blockquotes.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

49-49: Blank line inside blockquote
null

(MD028, no-blanks-blockquote)


55-68: Enhance Bullet Point Clarity in Requirements

The "Key-value pair requirements" list is very informative. However, consider rephrasing the bullet items at lines 64 and 67 (e.g. "Arrays can be empty" and "Dictionaries can be empty") so that each point forms a complete sentence, thereby improving readability and style.

🧰 Tools
🪛 LanguageTool

[style] ~64-~64: To form a complete sentence, be sure to include a subject.
Context: ..., dictionaries, or nested arrays. - can be empty. - Dictionaries (dict), wh...

(MISSING_IT_THERE)


[style] ~67-~67: To form a complete sentence, be sure to include a subject.
Context: ...tioned rules for keys and values. - can be empty. #### Automatically generated...

(MISSING_IT_THERE)


93-112: Example Code Quality and File Handling Consideration

The provided example code effectively demonstrates the usage of ClpKeyValuePairStreamHandler. As a suggestion, consider using a context manager (e.g. using with open(Path("example.clp.zst"), "wb") as f:) to ensure that the file handle is properly closed after logging operations.


358-363: Unused Link Reference Definition

The link reference definition for [clp-ffi-py-kv-pair-ir-stream] does not appear to be used anywhere in the document. Consider removing it to keep the documentation concise and avoid potential confusion.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

360-360: Link and image reference definitions should be needed
Unused link or image reference definition: "clp-ffi-py-kv-pair-ir-stream"

(MD053, link-image-reference-definitions)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ece534 and 33dc514.

📒 Files selected for processing (1)
  • README.md (2 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md

[style] ~64-~64: To form a complete sentence, be sure to include a subject.
Context: ..., dictionaries, or nested arrays. - can be empty. - Dictionaries (dict), wh...

(MISSING_IT_THERE)


[style] ~67-~67: To form a complete sentence, be sure to include a subject.
Context: ...tioned rules for keys and values. - can be empty. #### Automatically generated...

(MISSING_IT_THERE)

🪛 markdownlint-cli2 (0.17.2)
README.md

49-49: Blank line inside blockquote
null

(MD028, no-blanks-blockquote)


360-360: Link and image reference definitions should be needed
Unused link or image reference definition: "clp-ffi-py-kv-pair-ir-stream"

(MD053, link-image-reference-definitions)

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: test (ubuntu-latest, 3.11)
  • GitHub Check: test (ubuntu-latest, 3.8)
  • GitHub Check: test-python37 (ubuntu-22.04, 3.7)
  • GitHub Check: test (macos-latest, 3.8)
  • GitHub Check: test-python37 (macos-13, 3.7)
🔇 Additional comments (5)
README.md (5)

33-39: New Logging handlers Section Addition

The newly added section uses clear headings (e.g. "## Logging handlers" and "### ClpKeyValuePairStreamHandler") and appropriately highlights the version update with a release note. This clearly signals to users the introduction of the new handler.


40-44: Comprehensive Handler Functionality Description

The paragraph explains that the handler writes structured log events to the CLP IR stream and specifies how keys and metadata are handled. This information is concise and informative.


69-78: Well-Documented Auto-generated KV-Pairs Section

The explanation of automatically generated kv-pairs is concise and clear, effectively guiding the reader on how metadata is appended with each log event.


79-92: Clear Presentation of Auto-generated KV-Pair Details

The table format neatly summarises the auto-generated kv-pair information, making it easy for users to understand the structure of each log event’s metadata.


113-122: Clear Guidance on Reading KV-Pair IR Streams

This section offers a succinct list of the available options for reading and deserializing kv-pair IR streams, complete with useful links and examples.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
README.md (4)

46-53: Blockquote Formatting and Content

The note and warning blocks are informative. However, a minor nitpick: a blank line inside the blockquote (as flagged by markdownlint) might affect rendering consistency. Consider removing or consolidating the blank line within the blockquote to adhere to [MD028] guidelines.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

49-49: Blank line inside blockquote
null

(MD028, no-blanks-blockquote)


55-67: Key-Value Pair Requirements Clarity

The bullet list under "Key-value pair requirements" is comprehensive. As a minor suggestion, consider rephrasing the items in lines 64 and 67 to include a subject (e.g., "Each array can be empty." / "Each dictionary can be empty.") which may improve clarity for readers who prefer complete sentence constructions.

🧰 Tools
🪛 LanguageTool

[style] ~64-~64: To form a complete sentence, be sure to include a subject.
Context: ..., dictionaries, or nested arrays. - can be empty. - Dictionaries (dict), wh...

(MISSING_IT_THERE)


[style] ~67-~67: To form a complete sentence, be sure to include a subject.
Context: ...tioned rules for keys and values. - can be empty. #### Automatically generated...

(MISSING_IT_THERE)


93-111: Example Code for ClpKeyValuePairStreamHandler

The example code snippet is straightforward and demonstrates the intended usage of the handler. One small suggestion: although it is an example, consider using a context manager (the with statement) when opening files to promote best practices for resource management in real-world applications.


40-50: Additional Content Consideration Based on Past Feedback

Past review comments mentioned possibly referencing the log viewer and clarifying that the generated IR stream can be directly ingested into clp-s. While the log viewer is already mentioned, you might consider adding a brief sentence in this new section (or a subsequent update) to mention the potential for direct ingestion into clp-s. This could further assist users in understanding integrations available with the handler.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

49-49: Blank line inside blockquote
null

(MD028, no-blanks-blockquote)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33dc514 and 935202d.

📒 Files selected for processing (1)
  • README.md (2 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md

[style] ~64-~64: To form a complete sentence, be sure to include a subject.
Context: ..., dictionaries, or nested arrays. - can be empty. - Dictionaries (dict), wh...

(MISSING_IT_THERE)


[style] ~67-~67: To form a complete sentence, be sure to include a subject.
Context: ...tioned rules for keys and values. - can be empty. #### Automatically generated...

(MISSING_IT_THERE)

🪛 markdownlint-cli2 (0.17.2)
README.md

49-49: Blank line inside blockquote
null

(MD028, no-blanks-blockquote)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test-python37 (ubuntu-22.04, 3.7)
  • GitHub Check: test (macos-latest, 3.8)
🔇 Additional comments (7)
README.md (7)

33-34: New Section Introduction Clarity

The new "## Logging handlers" section is well placed after "Quick Start" and clearly introduces the documentation update. This sets the stage nicely for the ensuing details on the ClpKeyValuePairStreamHandler.


36-39: Handler Title and Version Annotation

The "### ClpKeyValuePairStreamHandler" title coupled with the "⭐ New in v0.0.14" note effectively communicates the new feature’s introduction and version. This is clear and impactful.


40-44: Handler Description Detail

The descriptive paragraph explains the handler’s purpose and behaviour clearly. It concisely states how structured log events (in the form of Python dictionaries) are processed into the CLP key-value pair IR stream. This aligns well with the documented requirements.


69-77: Auto-generated KV-Pairs Section

The "Automatically generated kv-pairs" section clearly distinguishes between user-generated and system-generated keys. This detailed explanation and the included note effectively clarify potential key collisions.


81-91: Auto-generated KV-Pairs Table

The table detailing auto-generated kv-pairs is well-formatted and utilises markdown's table syntax effectively. This structured format enhances readability and quick reference for users.


113-122: Reading KV-Pair IR Streams Section

The section on "Reading kv-pair IR streams" is informative and clearly outlines the available options, including links to additional documentation. It effectively complements the new handler feature.


357-362: Link References and Documentation Consistency

The new link references for [clp-ffi-py-deserializer-doc], [clp-ffi-py-deserializer-example], [clp-ffi-py-pypi], and [py-logging-formatter] are clear and correctly positioned at the end of the document. This approach helps maintain a clean main text and provides easy access to detailed resources.

Copy link
Member Author

@LinZhihao-723 LinZhihao-723 left a comment

Choose a reason for hiding this comment

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

Some trivial suggestions. The overall modification lgtm

LinZhihao-723 and others added 3 commits February 19, 2025 01:00
Co-authored-by: Lin Zhihao <59785146+LinZhihao-723@users.noreply.github.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
README.md (3)

33-33: Blank Line Consistency:
A new blank line was inserted on line 33. Please verify that this spacing is consistent with other section breaks in the document.


56-68: Key-Value Pair Requirements Clarity:
The bullet-list of key-value requirements is comprehensive. To enhance readability, consider rephrasing some bullet items as complete sentences (e.g. "Arrays may contain primitive values, dictionaries, or nested arrays and can be empty."). This would ensure clarity for all readers.

🧰 Tools
🪛 LanguageTool

[style] ~65-~65: To form a complete sentence, be sure to include a subject.
Context: ..., dictionaries, or nested arrays. - can be empty. - Dictionaries (dict), wh...

(MISSING_IT_THERE)


[style] ~68-~68: To form a complete sentence, be sure to include a subject.
Context: ...tioned rules for keys and values. - can be empty. #### Automatically generated...

(MISSING_IT_THERE)


94-112: Example Code Quality:
The example demonstrating the usage of ClpKeyValuePairStreamHandler is succinct and clear. For improved clarity, consider adding inline comments within the code snippet to briefly explain each step.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 935202d and 083eaec.

📒 Files selected for processing (1)
  • README.md (2 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md

[style] ~65-~65: To form a complete sentence, be sure to include a subject.
Context: ..., dictionaries, or nested arrays. - can be empty. - Dictionaries (dict), wh...

(MISSING_IT_THERE)


[style] ~68-~68: To form a complete sentence, be sure to include a subject.
Context: ...tioned rules for keys and values. - can be empty. #### Automatically generated...

(MISSING_IT_THERE)

🪛 markdownlint-cli2 (0.17.2)
README.md

50-50: Blank line inside blockquote
null

(MD028, no-blanks-blockquote)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test (macos-latest, 3.8)
  • GitHub Check: test-python37 (macos-13, 3.7)
🔇 Additional comments (9)
README.md (9)

34-34: New Section: "Logging handlers" Added
This new section provides a clear separation for logging handler documentation. The title is concise and appropriately placed.


36-36: Subsection Title Clarity:
"### ClpKeyValuePairStreamHandler" clearly identifies the handler being documented.


38-38: Version Indicator Notation:
The inclusion of "⭐ New in v0.0.14" effectively highlights the introduction of this handler in the specified version.


40-44: Handler Description Clarity:
The paragraph explaining what the handler does is clear and informative. It outlines the purpose and functionality well. Please ensure that key terminology (e.g. “kv-pair” and “IR stream format”) consistently matches internal documentation and implementation.


46-50: Informational Note on Formatter:
The note properly explains that the handler does not support setting a formatter because it deals with structured log events. Additionally, consider checking for any unnecessary blank lines within the blockquote that might trigger markdownlint (MD028) warnings.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

50-50: Blank line inside blockquote
null

(MD028, no-blanks-blockquote)


51-55: Warning About CLPLogLevelTimeout:
The warning block clearly informs the user that ClpKeyValuePairStreamHandler currently does not support CLPLogLevelTimeout and that this feature will be added in a future release.


70-79: Auto-Generated KV-Pairs Section:
The section distinguishing user-generated from auto-generated kv-pairs is well written and informative. It clearly lays out the additional metadata included with each log event.


80-92: KV-Pairs Table Formatting:
The table detailing the auto-generated kv-pairs is easy to read and provides valuable quick-reference information.


359-362: Updated Reference Links:
The newly added link definitions for [clp-ffi-py-deserializer-doc], [clp-ffi-py-deserializer-example], [clp-ffi-py-pypi], and [py-logging-formatter] appear to be correct. Please double-check that all URLs are current and that the anchors used in the document match these references.

Copy link
Member Author

@LinZhihao-723 LinZhihao-723 left a comment

Choose a reason for hiding this comment

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

I don't have any more comments.

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