Skip to content

v2.7.3: 新增任务上下文,方便以任务维度统计日志; download API 参数精简,jm-view-server改名兼容; 完善任务日志及下载 API 使用文档 - #554

Open
hect0x7 wants to merge 8 commits into
masterfrom
dev
Open

v2.7.3: 新增任务上下文,方便以任务维度统计日志; download API 参数精简,jm-view-server改名兼容; 完善任务日志及下载 API 使用文档#554
hect0x7 wants to merge 8 commits into
masterfrom
dev

Conversation

@hect0x7

@hect0x7 hect0x7 commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Clarify callback and batch exception contracts, add task-scoped logging across sync and async workers, and update the mobile API version.

Summary by CodeRabbit

  • New Features
    • Added task-aware, stable correlation in logs for concurrent troubleshooting.
    • Exposed current execution context to plugins and features.
  • Bug Fixes
    • Improved consistency of task-context propagation across sync, async, threaded, and decode-pool execution.
  • Documentation
    • Updated tutorials and API docs to clarify download event customization, batch partial-failure handling, and standardized “event” terminology.
  • Breaking Changes
    • Removed public callback parameters from single-album/single-photo APIs; check_exception is now keyword-only.
  • Chores
    • Updated CLI/docs/tests for the supported module and added a deprecation warning for legacy CLI imports.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change adds task-local context propagation across synchronous, asynchronous, threaded, and plugin execution paths. Public download callbacks are removed, exception options become keyword-only, logs include task identifiers, the CLI gains a deprecation shim, and documentation and tests are updated.

Changes

Task Context and Download APIs

Layer / File(s) Summary
Context foundation and public API contract
src/jmcomic/jm_task_context.py, src/jmcomic/api.py, src/jmcomic/__init__.py, tests/test_jmcomic/test_jm_api.py, tests/test_jmcomic/test_jm_async_api.py, assets/docs/sources/tutorial/*, assets/docs/sources/option_file_syntax.md, README.md
Adds ContextVar-based task context management, removes callback parameters from public download APIs, makes exception options keyword-only, preserves batch failure collection, and updates related documentation.
Context propagation across executors
src/jmcomic/jm_async_downloader.py, src/jmcomic/jm_client_impl.py, src/jmcomic/jm_downloader.py, src/jmcomic/jm_feature.py, src/jmcomic/jm_plugin.py
Binds task context across decode pools, thread pools, downloader branches, proxy fetches, plugins, and feature invocations.
Contextual logging and validation
src/jmcomic/jm_config.py, assets/docs/sources/tutorial/11_log_custom.md, tests/test_jmcomic/test_jm_task_context.py
Adds task-context log prefixes and formatter support, documents logging filters and concurrent task context, and tests formatting, propagation, and isolation behavior.
CLI compatibility migration
src/jmcomic/cl.py, assets/docs/sources/api/command-line.md, tests/test_jmcomic/test_jm_cli.py, usage/workflow_download.py
Updates CLI references to jmcomic.cli while retaining jmcomic.cl as a deprecation and re-export shim.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant DownloadAPI
  participant Executor
  participant Logger
  Caller->>DownloadAPI: start download
  DownloadAPI->>DownloadAPI: set jm_task_context
  DownloadAPI->>Executor: run bound task
  Executor-->>Logger: emit contextual record
  Logger-->>Caller: formatted task-aware log
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main changes: task context logging, download API simplification, and docs updates.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Clarify callback and batch exception contracts, add task-scoped logging across sync and async workers, and update the mobile API version.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@assets/docs/sources/tutorial/11_log_custom.md`:
- Line 117: Update the formatter assignment in the custom logging example to
avoid indexing jm_logger.handlers when no handlers are configured. Reuse the
first handler’s formatter when available, and otherwise apply a valid formatter
fallback before registering TaskLogHandler.

In `@assets/docs/sources/tutorial/4_module_custom.md`:
- Around line 20-22: Update the after_album override in the tutorial example to
delegate to JmDownloader.after_album by calling super().after_album(album),
while retaining the existing custom print behavior and choosing an appropriate
call order.

In `@README.md`:
- Line 241: Update the README bullet describing download event callbacks to
state that users must customize the behavior through a custom Downloader, such
as by subclassing or configuring it, rather than implying a public callback
parameter.

In `@src/jmcomic/__init__.py`:
- Line 7: Replace the star import from jm_task_context in the package
initializer with an explicit import of JM_TASK_CONTEXT, jm_task_context,
get_jm_task_context, and bind_jm_task_context, preserving the existing
package-level API.

In `@src/jmcomic/jm_task_context.py`:
- Around line 41-45: Update bind_jm_task_context to validate func with
callable(func) before async detection or wrapping, rejecting non-callable
targets immediately. Retain the existing __call__ inspection only for
identifying asynchronous callable objects, and preserve the current TypeError
behavior for unsupported async callables.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 62f4de3f-407c-4dcd-b46a-c5266f1923e5

📥 Commits

Reviewing files that changed from the base of the PR and between 2d03218 and f2cd00f.

📒 Files selected for processing (18)
  • README.md
  • assets/docs/sources/option_file_syntax.md
  • assets/docs/sources/tutorial/0_common_usage.md
  • assets/docs/sources/tutorial/11_log_custom.md
  • assets/docs/sources/tutorial/13_export_and_feature.md
  • assets/docs/sources/tutorial/4_module_custom.md
  • src/jmcomic/__init__.py
  • src/jmcomic/api.py
  • src/jmcomic/jm_async_downloader.py
  • src/jmcomic/jm_client_impl.py
  • src/jmcomic/jm_config.py
  • src/jmcomic/jm_downloader.py
  • src/jmcomic/jm_feature.py
  • src/jmcomic/jm_plugin.py
  • src/jmcomic/jm_task_context.py
  • tests/test_jmcomic/test_jm_api.py
  • tests/test_jmcomic/test_jm_async_api.py
  • tests/test_jmcomic/test_jm_task_context.py
💤 Files with no reviewable changes (1)
  • tests/test_jmcomic/test_jm_async_api.py

Comment thread assets/docs/sources/tutorial/11_log_custom.md
Comment thread assets/docs/sources/tutorial/4_module_custom.md
Comment thread README.md
Comment thread src/jmcomic/__init__.py
Comment thread src/jmcomic/jm_task_context.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/jmcomic/jm_config.py`:
- Line 612: Update the docstring for the ANSI-colored log formatter to replace
the fullwidth comma with an ASCII comma, preserving the existing wording and
behavior so Ruff’s RUF002 check passes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e859f80d-a09f-4951-b6c7-450765bd029c

📥 Commits

Reviewing files that changed from the base of the PR and between f2cd00f and e39c191.

📒 Files selected for processing (18)
  • README.md
  • assets/docs/sources/option_file_syntax.md
  • assets/docs/sources/tutorial/0_common_usage.md
  • assets/docs/sources/tutorial/11_log_custom.md
  • assets/docs/sources/tutorial/13_export_and_feature.md
  • assets/docs/sources/tutorial/4_module_custom.md
  • src/jmcomic/__init__.py
  • src/jmcomic/api.py
  • src/jmcomic/jm_async_downloader.py
  • src/jmcomic/jm_client_impl.py
  • src/jmcomic/jm_config.py
  • src/jmcomic/jm_downloader.py
  • src/jmcomic/jm_feature.py
  • src/jmcomic/jm_plugin.py
  • src/jmcomic/jm_task_context.py
  • tests/test_jmcomic/test_jm_api.py
  • tests/test_jmcomic/test_jm_async_api.py
  • tests/test_jmcomic/test_jm_task_context.py
💤 Files with no reviewable changes (1)
  • tests/test_jmcomic/test_jm_async_api.py
🚧 Files skipped from review as they are similar to previous changes (11)
  • README.md
  • src/jmcomic/jm_plugin.py
  • src/jmcomic/jm_feature.py
  • src/jmcomic/jm_client_impl.py
  • src/jmcomic/jm_downloader.py
  • assets/docs/sources/option_file_syntax.md
  • assets/docs/sources/tutorial/13_export_and_feature.md
  • assets/docs/sources/tutorial/0_common_usage.md
  • assets/docs/sources/tutorial/4_module_custom.md
  • assets/docs/sources/tutorial/11_log_custom.md
  • src/jmcomic/jm_async_downloader.py

Comment thread src/jmcomic/jm_config.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/jmcomic/jm_config.py`:
- Line 23: Update the comment near the task_context logging logic in
jm_config.py by replacing both fullwidth commas with ASCII commas, resolving the
remaining RUF003 lint violation without changing the code behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ac8cb86d-a8a0-47ed-ac2b-4a2924e8179b

📥 Commits

Reviewing files that changed from the base of the PR and between e39c191 and 0ecfb14.

📒 Files selected for processing (6)
  • assets/docs/sources/api/command-line.md
  • src/jmcomic/cl.py
  • src/jmcomic/jm_config.py
  • tests/test_jmcomic/test_jm_cli.py
  • tests/test_jmcomic/test_jm_task_context.py
  • usage/workflow_download.py
💤 Files with no reviewable changes (1)
  • src/jmcomic/cl.py

Comment thread src/jmcomic/jm_config.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/jmcomic/cl.py`:
- Line 3: Resolve the F403 lint error on the compatibility re-export in cl.py by
either replacing the wildcard import with an explicit __all__-driven export or
adding a narrowly scoped # noqa: F403 when preserving wildcard behavior is
required; keep the shim’s public API unchanged.

In `@tests/test_jmcomic/test_jm_cli.py`:
- Around line 13-17: Update test_cl_deprecated to remove the cached jmcomic.cl
entry from sys.modules before entering assertWarnsRegex, then perform the
deprecated import and preserve the existing identity assertion. Ensure the test
observes the module-level deprecation warning regardless of prior import order.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bb4df826-9b7f-4a5d-9a6d-519d4ea757e6

📥 Commits

Reviewing files that changed from the base of the PR and between 0ecfb14 and 33f2400.

📒 Files selected for processing (3)
  • assets/docs/sources/tutorial/11_log_custom.md
  • src/jmcomic/cl.py
  • tests/test_jmcomic/test_jm_cli.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • assets/docs/sources/tutorial/11_log_custom.md

Comment thread src/jmcomic/cl.py
@@ -1,9 +1,11 @@
import warnings

from .cli import *

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Resolve the intentional wildcard-import lint error.

Ruff reports F403 on this compatibility re-export. Keep the shim’s public surface explicit with an __all__-driven export, or add a narrowly scoped # noqa: F403 if the wildcard behavior is required.

🧰 Tools
🪛 Ruff (0.16.0)

[error] 3-3: from .cli import * used; unable to detect undefined names

(F403)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/jmcomic/cl.py` at line 3, Resolve the F403 lint error on the
compatibility re-export in cl.py by either replacing the wildcard import with an
explicit __all__-driven export or adding a narrowly scoped # noqa: F403 when
preserving wildcard behavior is required; keep the shim’s public API unchanged.

Source: Linters/SAST tools

Comment on lines +13 to +17
def test_cl_deprecated(self):
with self.assertWarnsRegex(DeprecationWarning, r'removed in version 2\.7\.4'):
from jmcomic.cl import JmcomicUI as DeprecatedJmcomicUI

self.assertIs(DeprecatedJmcomicUI, JmcomicUI)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(test_jm_cli\.py|cl\.py)$|src/jmcomic/cl\.py' || true

echo "== target test =="
cat -n tests/test_jmcomic/test_jm_cli.py | sed -n '1,80p'

echo "== cl.py warning code =="
cat -n src/jmcomic/cl.py | sed -n '1,120p'

echo "== imports of jmcomic.cl =="
rg -n "from jmcomic\.cl import|import jmcomic\.cl|jmcomic\.cl" tests src || true

echo "== Python module import behavior probe =="
python3 - <<'PY'
import warnings
import tempfile
import pathlib

p = pathlib.Path(tempfile.mkdtemp(), "mymod.py")
p.write_text("import warnings\nwarnings.warn('cached?', DeprecationWarning, stacklevel=1)\nvalue = 1\n")
warnings.filterwarnings("always", category=DeprecationWarning)

from importlib import import_module, reload
import sys

with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always", DeprecationWarning)
    m = import_module(p.stem)
    print("first_import_values:", m.value, "warnings:", len(w), [str(x.message) for x in w if x.category == DeprecationWarning])

with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always", DeprecationWarning)
    loaded = import_module(p.stem)
    print("second_import_same_values:", m is loaded, loaded.value, "warnings:", len(w), [str(x.message) for x in w if x.category == DeprecationWarning])

with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always", DeprecationWarning)
    reloaded = reload(m)
    print("reload_same_values:", reloaded is m, reloaded.value, "warnings:", len(w), [str(x.message) for x in w if x.category == DeprecationWarning])

del sys.modules[m.__name__]
with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always", DeprecationWarning)
    fresh = import_module(p.stem)
    print("fresh_after_reload_import_values:", fresh.value, "warnings:", len(w), [str(x.message) for x in w if x.component.category == DeprecationWarning for x in w] if False else len([x.message for x in w if x.category == DeprecationWarning]))
PY

Repository: hect0x7/JMComic-Crawler-Python

Length of output: 4833


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== test setup/base =="
for f in $(git ls-files | rg '(^|/)test_jmcomic/test_configurable\.py$|(^|/)(test_.*\.py|.*\.py)$' | rg 'test_jmcomic'); do
  echo "--- $f"
  wc -l "$f"
done
cat -n tests/test_jmcomic/test_configurable.py | sed -n '1,220p' || true

echo "== jmcomic package imports for cl imports =="
rg -n "from jmcomic\.cl import|import jmcomic\.cl|jmcomic\.cl" tests/jmcomic tests src || true

echo "== Python module caching probe (no installed package) =="
python3 - <<'PY'
import warnings
import tempfile
import pathlib
import sys

d = pathlib.Path(tempfile.mkdtemp())
(d / "pkg").mkdir()
(d / "pkg" / "__init__.py").write_text("")
(d / "pkg" / "pkgmod.py").write_text("""
import warnings
warnings.warn("cached?", DeprecationWarning, stacklevel=3)
value = 1
""")

sys.path.insert(0, str(d))
del sys.modules["pkg"]
if "pkg.pkgmod" in sys.modules:
    del sys.modules["pkg.pkgmod"]

with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always")
    import pkg.pkgmod  # first import
    print("first_import_first_loaded", pkg.pkgmod is sys.modules.get("pkg.pkgmod"))
    print("first_import_warning_count", len(w), [str(m.message) for m in w if m.category is DeprecationWarning])

with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always")
    from pkg.pkgmod import pkgmod  # cached import
    print("cached_after_cached_import_warning_count", len(w), [str(m.message) for m in w if m.category is DeprecationWarning])

from importlib import reload
with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always")
    reload(pkg.pkgmod)
    print("reload_import_warning_count", len(w), [str(m.message) for m in w if m.category is DeprecationWarning])
PY

Repository: hect0x7/JMComic-Crawler-Python

Length of output: 1902


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== test init =="
cat -n tests/test_jmcomic/__init__.py | sed -n '1,220p'

echo "== current test diff/stat if available =="
git diff -- tests/test_jmcomic/test_jm_cli.py src/jmcomic/cl.py tests/test_jmcomic/test_jm_cli.py | sed -n '1,220p'

echo "== Python import cache behavior with real module shape (standalone temp package) =="
python3 - <<'PY'
import warnings
import tempfile
import pathlib
import sys
import os

d = pathlib.Path(tempfile.mkdtemp())
(d / "pkg").mkdir()
(d / "pkg" / "__init__.py").write_text("from .pkgmod import *\n")
(d / "pkg" / "pkgmod.py").write_text("""
import warnings
warnings.warn("pkgmod cached warning", DeprecationWarning, stacklevel=2)
value = 1
""")

sys.path.insert(0, str(d))

with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always")
    import pkg
    print("first_import_warnings", len(w), [str(x.message) for x in w if x.category is DeprecationWarning])

with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always")
    from pkg import pkgmod
    print("cached_import_warnings", len(w), [str(x.message) for x in w if x.category is DeprecationWarning])

from importlib import reload
with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always")
    reload(pkg.pkgmod)
    print("reload_after_cached_warnings", len(w), [str(x.message) for x in w if x.category is DeprecationWarning])
PY

Repository: hect0x7/JMComic-Crawler-Python

Length of output: 7917


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== package exports =="
sed -n '1,220p' src/jmcomic/__init__.py
echo "---"
fd -e py . src/jmcomic | sort | while read -r f; do
  echo "--- $f"
  rg -n "from \.cli import|from \. import|import .*cl|cli\.|JmcomicUI|JmViewUI|warnings\.warn" "$f" || true
done
echo "== jmcomic subpackage cl import from cli =="
rg -n "from \.cli import|warnings\.warn" src/jmcomic || true

Repository: hect0x7/JMComic-Crawler-Python

Length of output: 2617


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== api.py get_env import section =="
sed -n '120,170p' src/jmcomic/api.py

echo "== all direct references to jmcomic.cli in src/tests =="
rg -n "jmcomic\.cli|\.cli import|from \.cl import|import\s+cl|cl\.py" src tests || true

echo "== Python behavior probe using the exact jmcomic source relationship =="
tmp="$(mktemp -d)"
mkdir -p "$tmp/jmcomic"
mkdir -p "$tmp/jmcomic/tests"
cat > "$tmp/jmcomic/__init__.py" <<'PY'
from .jm_plugin import *
from .api import *
PY
cat > "$tmp/jmcomic/jm_plugin.py" <<'PY'
pass
PY
cat > "$tmp/jmcomic/api.py" <<'PY'
def get_env():
    from .cli import JmcomicUI
    return JmcomicUI
PY
cat > "$tmp/jmcomic/cli.py" <<'PY'
class JmcomicUI:
    pass
PY
cat > "$tmp/jmcomic/cl.py" <<'PY'
import warnings
from .cli import *
warnings.warn("removed in version 2.7.4", DeprecationWarning, stacklevel=2)
PY
cat > "$tmp/jmcomic/tests/__init__.py" <<'PY'
import jmcomic
from jmcomic import *
PY
cat > "$tmp/tests.py" <<'PY'
from unittest import TestCase
import warnings


class TestCli(TestCase):
    def test_cl_deprecated_after_setup_imports_cli(self):
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always", DeprecationWarning)
            from jmcomic.cl import JmcomicUI as DeprecatedJmcomicUI
        print("warnings", len(w), [str(x.message) for x in w if x.category is DeprecationWarning])
        print("assertIs", DeprecatedJmcomicUI)


if __name__ == "__main__":
    import sys
    import unittest
    import jmcomic.tests
    unittest.main(argv=[sys.argv[0], "-v"])
PY

python3 - <<'PY'
import sys, warnings
warnings.filterwarnings("always", category=DeprecationWarning)
sys.path.insert(0, '/tmp')

class TC: pass
from jmcomic.tests import import_jmcomic_tests
print("setup_imported_jmcomic_tests", import_jmcomic_tests)
print("jmcomic_module_in_sys_modules", "jmcomic.cl" in sys.modules)
warnings.simplefilter("always", DeprecationWarning)
from jmcomic.cl import JmcomicUI as DeprecatedJmcomicUI
print("cached_deprecated_import_warnings", len([x for x in dir(TC) if False]))
PY

Repository: hect0x7/JMComic-Crawler-Python

Length of output: 2241


Make the deprecation test independent of module-import order.

jmcomic.cl emits its DeprecationWarning during module execution, but Python caches that module after the package test setup imports jmcomic; a later from jmcomic.cl import ... inside the assertWarnsRegex context will reuse the cached module and can fail to see the warning. Reloading is not enough in the normal test setup; isolate the import by removing jmcomic.cl from sys.modules before asserting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_jmcomic/test_jm_cli.py` around lines 13 - 17, Update
test_cl_deprecated to remove the cached jmcomic.cl entry from sys.modules before
entering assertWarnsRegex, then perform the deprecated import and preserve the
existing identity assertion. Ensure the test observes the module-level
deprecation warning regardless of prior import order.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/test_jmcomic/test_jm_task_context.py (1)

133-168: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert rendered task-context fields, not only color prefixes.

This test supplies task_id, download_type, and jm_id, but only checks startswith(...). A formatter that drops task-context data entirely would still pass. Assert that the formatted output contains the required identifiers to cover the logging contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_jmcomic/test_jm_task_context.py` around lines 133 - 168, Update
test_pretty_formatter_uses_topic_colors to retain its existing color-prefix
assertions and also verify that formatted output includes the task_context
identifiers task-A, album, and 1. Assert these values on the rendered output so
the test covers both color selection and task-context field rendering.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/test_jmcomic/test_jm_task_context.py`:
- Around line 133-168: Update test_pretty_formatter_uses_topic_colors to retain
its existing color-prefix assertions and also verify that formatted output
includes the task_context identifiers task-A, album, and 1. Assert these values
on the rendered output so the test covers both color selection and task-context
field rendering.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b306214b-cdc1-4ec4-a64f-f64113218d90

📥 Commits

Reviewing files that changed from the base of the PR and between 33f2400 and e858459.

📒 Files selected for processing (1)
  • tests/test_jmcomic/test_jm_task_context.py

@hect0x7 hect0x7 changed the title feat: improve download APIs and task logging v2.7.3: 新增任务上下文,方便以任务维度统计日志; download API 参数精简,jm-view-server改名兼容; 完善任务日志及下载 API 使用文档 Jul 30, 2026
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.

1 participant