Skip to content

Fix Pipfile parsing crashes with non-string values in libyear dependency metrics - #473

Draft
MoralCode wants to merge 1 commit into
mainfrom
zeba-source/fix-pipfile-parsing
Draft

MoralCode wants to merge 1 commit into
mainfrom
zeba-source/fix-pipfile-parsing

Conversation

@MoralCode

Copy link
Copy Markdown
Contributor

Note

This PR was ported from augurlabs/augur#3495 filed by @zeba-source because the contribution was deemed to still be useful.

Summary

Fixes #143

The libyear dependency metrics collection would crash when processing Pipfiles
containing non-string values (such as booleans, dicts, or other TOML types).
The code assumed all values in dependency-related sections were strings and
would fail with "Expecting something like a string" when encountering values
like allow_prereleases = true.

Root Cause

The error occurred when the code iterated over Pipfile sections and attempted
string operations (regex matching, version parsing) on non-string values without
type checking.

Example from the failing Pipfile:

[pipenv]
allow_prereleases = true  # Boolean causes crash

Changes Made

Core Fixes

  • Added normalize_pipfile_version() to safely handle all Pipfile value types
  • Added defensive type checks before string operations in downstream functions
  • Implemented Pipfile.lock preference over Pipfile (more reliable for version info)
  • Filters unsupported formats (path, editable, non-string) with debug logging

Testing

  • Added 26 comprehensive unit tests covering:
    • Boolean values in Pipfile sections
    • Inline table (dict) dependency specifications
    • Path and editable dependencies
    • Mixed string and non-string values
  • Includes reproduction script for verification

Files Modified

  • augur/tasks/git/dependency_libyear_tasks/libyear_util/pypi_parser.py
  • augur/tasks/git/dependency_libyear_tasks/libyear_util/pypi_libyear_util.py
  • augur/tasks/git/dependency_libyear_tasks/libyear_util/util.py

Files Added

  • tests/test_tasks/test_libyear_dependency_metrics.py (26 tests)
  • scripts/reproduce_issue_3430.py
  • tests/test_data/issue_3430_test_Pipfile
  • tests/test_data/REPRODUCTION_GUIDE.md

Backward Compatibility

Changes use defensive programming and are fully backward compatible. Valid
string dependencies continue to be processed normally; only non-string values
are skipped with appropriate logging.

AI disclosure

Yes, I used AI assistance (Claude/ChatGPT) to help with:

Understanding the Pipfile parsing error
Writing the fix for handling inline table dependencies
Creating the unit tests

I reviewed all AI-generated code and tested it locally before submitting.

… metrics

The libyear dependency metrics collection would crash when processing Pipfiles
with inline table (dict) dependency specifications. The code assumed all
dependency values were strings, but Pipfile format allows dicts for complex
specifications like extras, markers, and path dependencies.

This commit:
- Adds normalize_pipfile_version() to safely handle all Pipfile formats
- Adds defensive type checks before string operations in downstream functions
- Implements Pipfile.lock preference over Pipfile (more reliable)
- Filters unsupported formats (path, editable) with debug logging
- Adds 26 comprehensive unit tests
- Includes reproduction script for verification

Changes are backward compatible and use defensive programming to prevent
future crashes. Valid dependencies continue to be processed; only unsupported
formats (path, editable) are skipped with appropriate logging.

Files modified:
- augur/tasks/git/dependency_libyear_tasks/libyear_util/pypi_parser.py
- augur/tasks/git/dependency_libyear_tasks/libyear_util/pypi_libyear_util.py
- augur/tasks/git/dependency_libyear_tasks/libyear_util/util.py

Files added:
- tests/test_tasks/test_libyear_dependency_metrics.py (26 tests)
- scripts/reproduce_issue_3430.py
- tests/test_data/issue_3430_test_Pipfile
- tests/test_data/REPRODUCTION_GUIDE.md

Fixes #3430

Signed-off-by: Zeba Fatma Khan <khanz@rknec.edu>
Tests specifically address issue #3430: Pipfile parsing failures with inline table dependencies.
"""
import pytest
import tempfile

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[pylint] reported by reviewdog 🐶
W0611: Unused import tempfile (unused-import)

"""
import pytest
import tempfile
import os

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[pylint] reported by reviewdog 🐶
W0611: Unused import os (unused-import)

import tempfile
import os
from io import BytesIO
import logging

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[pylint] reported by reviewdog 🐶
W0611: Unused import logging (unused-import)

@MoralCode

Copy link
Copy Markdown
Contributor Author
  • needs check for any legacy variable/project names

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.

process_libyear_dependency_metrics error: Expecting something like a string

2 participants