Skip to content

fix(encoding): handle non-UTF-8 system encoding in subprocess output#303

Merged
dd-jy merged 2 commits intomainfrom
encode
Apr 3, 2026
Merged

fix(encoding): handle non-UTF-8 system encoding in subprocess output#303
dd-jy merged 2 commits intomainfrom
encode

Conversation

@dd-jy
Copy link
Copy Markdown
Contributor

@dd-jy dd-jy commented Apr 3, 2026

Description

fix(encoding): handle non-UTF-8 system encoding in subprocess output

  • Add decode_subprocess_output() utility in _package_manager.py
    to safely decode subprocess output using locale-aware fallback
    (UTF-8 → system encoding → replace)
  • Apply decode_subprocess_output() in Yarn.detect_yarn_version()
    to handle cp949/euc-kr and other non-UTF-8 system encodings
  • Apply decode_subprocess_output() in Npm.parse_transitive_relationship()
    to fix UnicodeDecodeError in _readerthread on non-UTF-8 systems

Summary by CodeRabbit

  • Bug Fixes

    • More reliable subprocess output decoding (UTF‑8-first with safe fallback) across package managers
    • Clearer, decoded stderr in error and warning messages for CLI tools
    • Consistent environment handling for Python tooling and more robust command return‑code checks
    • Improved version detection for JS tooling via safer output decoding
  • Chores

    • Removed packaging entry that bundled extra LICENSES files from the distributed package

Signed-off-by: 석지영 <jiyeong.seok@lge.com>
@dd-jy dd-jy self-assigned this Apr 3, 2026
@dd-jy dd-jy added the bug fix [PR] Fix the bug label Apr 3, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 3, 2026

Warning

Rate limit exceeded

@dd-jy has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 19 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 2 minutes and 19 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 352b2e9f-93c7-4f06-9da1-cd5dc4bdfe70

📥 Commits

Reviewing files that changed from the base of the PR and between aacc1fa and e763c36.

📒 Files selected for processing (2)
  • pyproject.toml
  • src/fosslight_dependency/_package_manager.py
📝 Walkthrough

Walkthrough

Added UTF‑8-first subprocess output decoding and helper wrappers; updated Npm, Pypi, Yarn, and PackageManager code to use decoded outputs and improved pip/virtualenv environment handling; removed package-data entry for LICENSES in pyproject.toml.

Changes

Cohort / File(s) Summary
Core decoding & subprocess helpers
src/fosslight_dependency/_package_manager.py
Added decode_subprocess_output(), run_command(), and check_output_safe(); replaced direct subprocess.check_output(..., encoding='utf-8') calls in PackageManager.run_gradle_task() with check_output_safe() and adjusted related result handling.
Npm package manager
src/fosslight_dependency/package_manager/Npm.py
Switched to capturing raw bytes from subprocess runs and decoding stdout/stderr via decode_subprocess_output(); updated error/warning logging to use decoded stderr.
Pypi package manager
src/fosslight_dependency/package_manager/Pypi.py
Set PYTHONUTF8=1 in env for virtualenv and pip commands, changed some subprocess.call() to subprocess.run(..., env=..., stderr=...), decode stderr for error messages, and added --no-color to pip inspect.
Yarn package manager
src/fosslight_dependency/package_manager/Yarn.py
Removed text=True/encoding='utf-8' from yarn -v invocation and now decodes result.stdout with decode_subprocess_output() before parsing the version.
Packaging config
pyproject.toml
Removed [tool.setuptools.package-data] entry that previously included LICENSES/* in package data.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

chore

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: introducing a subprocess encoding utility and applying it to handle non-UTF-8 system encodings across multiple package managers.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch encode

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 and usage tips.

Copy link
Copy Markdown

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/fosslight_dependency/_package_manager.py (1)

158-163: ⚠️ Potential issue | 🟡 Minor

Remove the invalid 0 integer comparisons on the return value of check_output_safe().

check_output_safe() returns decoded stdout text (never raises if successful), not an integer. The comparisons ret != 0 and ret == 0 are always true and false respectively when comparing strings, making the else block and second if block dead code. Replace with checks for non-empty output using output.strip().

Proposed fix
-                        ret = check_output_safe(cmd, shell=True)
-                        if ret != 0:
-                            self.parse_dependency_tree(ret)
+                        output = check_output_safe(cmd, shell=True)
+                        if output.strip():
+                            self.parse_dependency_tree(output)
                         else:
                             self.set_direct_dependencies(False)
-                            logger.warning(f"Fail to run {cmd}")
+                            logger.warning(f"No output from {cmd}")
@@
-                        ret = check_output_safe(cmd, shell=True)
-                        if ret == 0:
-                            ret_task = False
-                            logger.error(f'Fail to run {cmd}')
+                        _ = check_output_safe(cmd, shell=True)

Also applies to: 171-174

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 158 - 163, The
code incorrectly treats the return value of check_output_safe() as an integer;
instead of comparing ret != 0 / ret == 0 you should check whether the returned
stdout is non-empty (e.g., if output and output.strip():). Update the two call
sites that use check_output_safe() in _package_manager.py (the blocks that call
parse_dependency_tree(ret) and set_direct_dependencies(False)) to use a string
emptiness check on the returned value (e.g., output = check_output_safe(...); if
output and output.strip(): parse_dependency_tree(output) else:
set_direct_dependencies(False) and logger.warning(...)). Ensure you use the same
variable name (ret or output) consistently and replace both occurrences
mentioned in the review.
🧹 Nitpick comments (4)
src/fosslight_dependency/package_manager/Pypi.py (3)

230-236: Apply the same refactor here for consistency.

Same redundant decoding pattern as the primary block. Decode stderr once after subprocess.run and reuse the variable.

♻️ Proposed refactor
                     cmd_ret = subprocess.run(cmd, shell=True, stderr=subprocess.PIPE, env=env)
+                    stderr_text = cmd_ret.stderr.decode('utf-8', errors='replace').strip()
                     if cmd_ret.returncode != 0:
                         ret = False
-                        err_msg = cmd_ret.stderr.decode('utf-8', errors='replace').strip() or f"return code({cmd_ret.returncode})"
-                    elif cmd_ret.stderr.decode('utf-8', errors='replace').strip().lower().startswith('error:'):
+                        err_msg = stderr_text or f"return code({cmd_ret.returncode})"
+                    elif stderr_text.lower().startswith('error:'):
                         ret = False
-                        err_msg = cmd_ret.stderr.decode('utf-8', errors='replace').strip()
+                        err_msg = stderr_text
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/package_manager/Pypi.py` around lines 230 - 236, In
Pypi.py where subprocess.run is invoked (the cmd_ret handling block), avoid
decoding stderr multiple times: after cmd_ret = subprocess.run(...,
stderr=subprocess.PIPE, env=env) decode stderr once into a variable (e.g.,
stderr = cmd_ret.stderr.decode('utf-8', errors='replace').strip()) and then use
that variable for the return-code error branch and the
stderr.startswtih('error:') branch to set ret and err_msg; update the block
around cmd_ret to reuse the single decoded stderr value for consistency with the
primary block.

211-218: Decode stderr once and reuse to avoid redundant decoding.

The stderr is decoded multiple times in this block. Decode once and store in a variable for both the error message assignment and the 'error:' prefix check.

♻️ Proposed refactor
-            cmd_ret = subprocess.run(cmd, shell=True, stderr=subprocess.PIPE, env=env)
+            cmd_ret = subprocess.run(cmd, shell=True, stderr=subprocess.PIPE, env=env)
+            stderr_text = cmd_ret.stderr.decode('utf-8', errors='replace').strip()
             if cmd_ret.returncode != 0:
                 ret = False
-                err_msg = cmd_ret.stderr.decode('utf-8', errors='replace').strip() or f"return code({cmd_ret.returncode})"
-            elif cmd_ret.stderr.decode('utf-8', errors='replace').strip().lower().startswith('error:'):
+                err_msg = stderr_text or f"return code({cmd_ret.returncode})"
+            elif stderr_text.lower().startswith('error:'):
                 ret = False
-                err_msg = cmd_ret.stderr.decode('utf-8', errors='replace').strip()
+                err_msg = stderr_text
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/package_manager/Pypi.py` around lines 211 - 218, In
the subprocess handling block around subprocess.run (look for cmd_ret variable
in Pypi.py), decode cmd_ret.stderr once into a local string (e.g., stderr_str =
(cmd_ret.stderr or b'').decode('utf-8', errors='replace').strip()) and then
reuse stderr_str for both the return-code error assignment and the
startswith('error:') check; set ret and err_msg based on stderr_str (or fallback
to f"return code({cmd_ret.returncode})" when empty) instead of decoding
cmd_ret.stderr multiple times.

215-218: Use the shared decode_subprocess_output() utility for consistency across package managers.

Pypi.py uses inline decode('utf-8', errors='replace') at multiple locations (lines 215–218, 233–236, 283, 339), while Yarn.py and Npm.py consistently use the shared decode_subprocess_output() utility from _package_manager.py. Import decode_subprocess_output and replace the inline decoding to maintain consistency across all package managers.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/package_manager/Pypi.py` around lines 215 - 218,
Replace all inline subprocess output decoding in
src/fosslight_dependency/package_manager/Pypi.py with the shared utility
decode_subprocess_output from _package_manager: add "from ._package_manager
import decode_subprocess_output" at the top and change every occurrence of
cmd_ret.stderr.decode('utf-8', errors='replace') and
cmd_ret.stdout.decode('utf-8', errors='replace') (e.g., the blocks that set
err_msg and ret based on cmd_ret) to use decode_subprocess_output(cmd_ret,
stream='stderr') or decode_subprocess_output(cmd_ret, stream='stdout') as
appropriate so decoding is consistent with Yarn/Npm modules.
src/fosslight_dependency/_package_manager.py (1)

43-44: Make shell execution opt-in in the shared helpers.

These wrappers centralize subprocess spawning. Keeping shell=True as the default makes future string commands shell out unless every caller remembers to override it. Safer default is shell=False, with explicit opt-in at the few sites that really need a shell. All existing callers already explicitly pass shell=True, so this change is safe.

Proposed fix
-def run_command(cmd, shell=True, cwd=None, env=None, timeout=None, capture_output=True):
+def run_command(cmd, shell=False, cwd=None, env=None, timeout=None, capture_output=True):
     kwargs = dict(shell=shell, capture_output=capture_output)
     if cwd:
         kwargs['cwd'] = cwd
@@
-def check_output_safe(cmd, shell=True, cwd=None):
+def check_output_safe(cmd, shell=False, cwd=None):
     result = subprocess.run(cmd, shell=shell, capture_output=True, cwd=cwd)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 43 - 44, The
run_command helper currently defaults to shell=True; change its signature to use
shell=False and build kwargs accordingly (e.g., kwargs = dict(shell=shell,
capture_output=capture_output)) so callers must opt in to shell usage; update
any call sites that rely on the old default to pass shell=True explicitly and
ensure run_command and its callers (function name: run_command) still pass
through cwd, env, timeout as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 30-40: The fallback encoding in decode_subprocess_output should
use the real system encoding via locale.getencoding() instead of
locale.getpreferredencoding(False), falling back to
locale.getpreferredencoding(False) on older Pythons; update the second try block
in decode_subprocess_output to call locale.getencoding() (with a fallback to
getpreferredencoding(False)) and then decode using that encoding, preserving the
existing error-handling branches and the final data.decode(..., errors=errors)
fallback.

---

Outside diff comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 158-163: The code incorrectly treats the return value of
check_output_safe() as an integer; instead of comparing ret != 0 / ret == 0 you
should check whether the returned stdout is non-empty (e.g., if output and
output.strip():). Update the two call sites that use check_output_safe() in
_package_manager.py (the blocks that call parse_dependency_tree(ret) and
set_direct_dependencies(False)) to use a string emptiness check on the returned
value (e.g., output = check_output_safe(...); if output and output.strip():
parse_dependency_tree(output) else: set_direct_dependencies(False) and
logger.warning(...)). Ensure you use the same variable name (ret or output)
consistently and replace both occurrences mentioned in the review.

---

Nitpick comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 43-44: The run_command helper currently defaults to shell=True;
change its signature to use shell=False and build kwargs accordingly (e.g.,
kwargs = dict(shell=shell, capture_output=capture_output)) so callers must opt
in to shell usage; update any call sites that rely on the old default to pass
shell=True explicitly and ensure run_command and its callers (function name:
run_command) still pass through cwd, env, timeout as before.

In `@src/fosslight_dependency/package_manager/Pypi.py`:
- Around line 230-236: In Pypi.py where subprocess.run is invoked (the cmd_ret
handling block), avoid decoding stderr multiple times: after cmd_ret =
subprocess.run(..., stderr=subprocess.PIPE, env=env) decode stderr once into a
variable (e.g., stderr = cmd_ret.stderr.decode('utf-8',
errors='replace').strip()) and then use that variable for the return-code error
branch and the stderr.startswtih('error:') branch to set ret and err_msg; update
the block around cmd_ret to reuse the single decoded stderr value for
consistency with the primary block.
- Around line 211-218: In the subprocess handling block around subprocess.run
(look for cmd_ret variable in Pypi.py), decode cmd_ret.stderr once into a local
string (e.g., stderr_str = (cmd_ret.stderr or b'').decode('utf-8',
errors='replace').strip()) and then reuse stderr_str for both the return-code
error assignment and the startswith('error:') check; set ret and err_msg based
on stderr_str (or fallback to f"return code({cmd_ret.returncode})" when empty)
instead of decoding cmd_ret.stderr multiple times.
- Around line 215-218: Replace all inline subprocess output decoding in
src/fosslight_dependency/package_manager/Pypi.py with the shared utility
decode_subprocess_output from _package_manager: add "from ._package_manager
import decode_subprocess_output" at the top and change every occurrence of
cmd_ret.stderr.decode('utf-8', errors='replace') and
cmd_ret.stdout.decode('utf-8', errors='replace') (e.g., the blocks that set
err_msg and ret based on cmd_ret) to use decode_subprocess_output(cmd_ret,
stream='stderr') or decode_subprocess_output(cmd_ret, stream='stdout') as
appropriate so decoding is consistent with Yarn/Npm modules.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 254427c9-5b92-4c33-b6c0-86f697745a06

📥 Commits

Reviewing files that changed from the base of the PR and between 31ece2e and 01030cb.

📒 Files selected for processing (4)
  • src/fosslight_dependency/_package_manager.py
  • src/fosslight_dependency/package_manager/Npm.py
  • src/fosslight_dependency/package_manager/Pypi.py
  • src/fosslight_dependency/package_manager/Yarn.py

Comment thread src/fosslight_dependency/_package_manager.py
Copy link
Copy Markdown

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/fosslight_dependency/_package_manager.py (1)

161-166: ⚠️ Potential issue | 🟠 Major

Fix impossible int checks against decoded stdout text.

check_output_safe() returns decoded stdout text (or raises), so checks like ret != 0 / ret == 0 are invalid and produce dead/misleading logic.

Proposed fix
-                        ret = check_output_safe(cmd, shell=True)
-                        if ret != 0:
-                            self.parse_dependency_tree(ret)
+                        output = check_output_safe(cmd, shell=True)
+                        if output.strip():
+                            self.parse_dependency_tree(output)
                         else:
                             self.set_direct_dependencies(False)
                             logger.warning(f"Fail to run {cmd}")
@@
-                        ret = check_output_safe(cmd, shell=True)
-                        if ret == 0:
-                            ret_task = False
-                            logger.error(f'Fail to run {cmd}')
+                        check_output_safe(cmd, shell=True)

Also applies to: 174-177

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 161 - 166, The
code incorrectly treats the decoded stdout from check_output_safe() as an int
and compares it to 0; update the logic in the block using check_output_safe,
parse_dependency_tree, set_direct_dependencies and logger.warning to treat ret
as text (use truthiness / non-empty string) and handle command failures via
exceptions: call check_output_safe(cmd, shell=True) inside a try/except, on
success if ret (non-empty string) call parse_dependency_tree(ret), otherwise
call set_direct_dependencies(False) and logger.warning(f"Fail to run {cmd}");
apply the same fix to the similar block that appears later (the second
occurrence mentioned for lines 174-177).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 52-53: The current conditional uses truthiness for timeout and
therefore skips valid falsy values like 0; update the check in the block that
sets kwargs (the code referencing timeout and kwargs) to use an explicit None
check (if timeout is not None:) so timeout=0 is preserved and only None is
omitted.
- Around line 46-47: Change the default shell behavior to avoid command
injection: update run_command and check_output_safe to default shell=False (or
remove the shell parameter) and require/accept argument lists instead of shell
strings; then refactor all callers that currently pass interpolated f-strings
(e.g., calls like check_output_safe(cmd, shell=True) where cmd = f"{cmd_gradle}
allDeps") to pass an argv list (e.g., [cmd_gradle, "allDeps"]) or use
shlex.split before calling; ensure subprocess invocations inside run_command and
check_output_safe use the list directly and only set shell=True when absolutely
necessary and explicitly reviewed.

---

Outside diff comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 161-166: The code incorrectly treats the decoded stdout from
check_output_safe() as an int and compares it to 0; update the logic in the
block using check_output_safe, parse_dependency_tree, set_direct_dependencies
and logger.warning to treat ret as text (use truthiness / non-empty string) and
handle command failures via exceptions: call check_output_safe(cmd, shell=True)
inside a try/except, on success if ret (non-empty string) call
parse_dependency_tree(ret), otherwise call set_direct_dependencies(False) and
logger.warning(f"Fail to run {cmd}"); apply the same fix to the similar block
that appears later (the second occurrence mentioned for lines 174-177).
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 89b2c489-ceff-4e95-b97a-1ef5dd8c2b19

📥 Commits

Reviewing files that changed from the base of the PR and between 01030cb and 1fa4deb.

📒 Files selected for processing (2)
  • pyproject.toml
  • src/fosslight_dependency/_package_manager.py
💤 Files with no reviewable changes (1)
  • pyproject.toml

Comment thread src/fosslight_dependency/_package_manager.py
Comment thread src/fosslight_dependency/_package_manager.py Outdated
Copy link
Copy Markdown

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/fosslight_dependency/_package_manager.py (1)

161-166: ⚠️ Potential issue | 🔴 Critical

Type mismatch: check_output_safe() returns a string, not an exit code.

check_output_safe() returns decoded stdout as a string, but line 162 compares it to integer 0. This comparison is always True for any string, making the else branch (lines 165-166) unreachable dead code. The logic should check for non-empty output instead.

Proposed fix
                     ret = check_output_safe(cmd, shell=True)
-                    if ret != 0:
+                    if ret:
                         self.parse_dependency_tree(ret)
                     else:
                         self.set_direct_dependencies(False)
                         logger.warning(f"Fail to run {cmd}")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 161 - 166, The
code incorrectly treats ret from check_output_safe(cmd, shell=True) as an exit
code; change the conditional to check for non-empty string output (e.g., if ret:
...) so that parse_dependency_tree(ret) runs when output exists and the else
branch calls self.set_direct_dependencies(False) and logger.warning(f"Fail to
run {cmd}") when ret is empty or falsy; update the block that references ret,
cmd, parse_dependency_tree and set_direct_dependencies accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 174-177: Remove the unreachable branch that checks "if ret == 0"
after calling check_output_safe(cmd, shell=True) in _package_manager:
check_output_safe returns a decoded string (or raises CalledProcessError on
failure), so the ret == 0 condition is always false; delete the if block that
sets ret_task = False and calls logger.error(f'Fail to run {cmd}'), leaving the
call to check_output_safe and existing except handling intact to report
failures.
- Around line 40-43: The current try/except around data.decode(system_encoding)
mishandles LookupError because retrying with the same invalid system_encoding
will raise again; update the code to handle UnicodeDecodeError and LookupError
separately: keep the UnicodeDecodeError branch to retry with
data.decode(system_encoding, errors=errors), but add a LookupError branch that
falls back to a known-good encoding (e.g., 'utf-8' or 'latin-1') and decodes
with data.decode(fallback_encoding, errors=errors). Reference the existing
symbols system_encoding, data.decode(...), and errors when implementing the
separate except clauses and the fallback decode.

---

Outside diff comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 161-166: The code incorrectly treats ret from
check_output_safe(cmd, shell=True) as an exit code; change the conditional to
check for non-empty string output (e.g., if ret: ...) so that
parse_dependency_tree(ret) runs when output exists and the else branch calls
self.set_direct_dependencies(False) and logger.warning(f"Fail to run {cmd}")
when ret is empty or falsy; update the block that references ret, cmd,
parse_dependency_tree and set_direct_dependencies accordingly.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ee7d60ac-85b5-481c-81b0-3193cff259fc

📥 Commits

Reviewing files that changed from the base of the PR and between 1fa4deb and aacc1fa.

📒 Files selected for processing (2)
  • pyproject.toml
  • src/fosslight_dependency/_package_manager.py
💤 Files with no reviewable changes (1)
  • pyproject.toml

Comment thread src/fosslight_dependency/_package_manager.py
Comment thread src/fosslight_dependency/_package_manager.py Outdated
@dd-jy dd-jy merged commit 2368bf5 into main Apr 3, 2026
13 checks passed
@dd-jy dd-jy deleted the encode branch April 3, 2026 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug fix [PR] Fix the bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant