Skip to content

Honor digit_group_separator's complementary decimal separator - #77

Open
binggao1230 wants to merge 3 commits into
scrapinghub:masterfrom
binggao1230:fix-digit-group-separator-decimal
Open

binggao1230 wants to merge 3 commits into
scrapinghub:masterfrom
binggao1230:fix-digit-group-separator-decimal

Conversation

@binggao1230

Copy link
Copy Markdown

Summary

Price.fromstring documents that digit_group_separator implies the complementary decimal separator:

If digit_group_separator is ".", then 1.000 is parsed as 1000. If it is ",", then 1.000 is parsed as 1.

The "," case is broken:

>>> from price_parser import Price
>>> Price.fromstring("1.000", digit_group_separator=",").amount
Decimal('1000')        # docstring says this should be 1 (i.e. Decimal('1.000'))

fromstring strips the group separator but leaves decimal_separator=None, so parse_number re-guesses the remaining ./, — and for "1.000" it guesses the . is a thousands group. The sibling paths confirm the inconsistency: decimal_separator="." on the same input correctly gives Decimal('1.000'), and digit_group_separator="." correctly gives 1000 — only the ","-group branch was wrong.

Fix

When the caller declares one of "."/"," as the digit group separator and passes no explicit decimal_separator, treat the other symbol as the decimal separator — exactly the documented semantics:

if decimal_separator is None and digit_group_separator in (".", ","):
    decimal_separator = "," if digit_group_separator == "." else "."

Non-./, group separators (e.g. a space) and the explicit-decimal_separator path are unaffected.

Verification

  • Reproduced on master (64e213a): all four docstring claims now hold, and mixed inputs like "1,000.50" (group=","1000.50) and "1.000,50" (group="."1000.50) parse correctly.
  • Added a parametrized test_price_digit_group_separator mirroring test_price_decimal_separator; the documented ","-group case fails before the fix and passes after.
  • Full suite: 1065 passed, 134 xfailed (baseline 1059 passed + 6 new params), no regressions. ruff and mypy clean.

This pull request was prepared with the assistance of AI, under my direction and review.

Price.fromstring documents that passing digit_group_separator=","
parses "1.000" as 1 (the "." being the decimal separator), and
symmetrically for ".". It stripped the group separator but left
decimal_separator as None, so parse_number re-guessed the remaining
"." or "," and produced the wrong amount (e.g. "1.000" -> 1000).

When the caller declares one of "."/"," as the digit group separator
and passes no explicit decimal_separator, treat the other symbol as the
decimal separator, matching the documented behaviour. Other separators
(e.g. space) and the explicit decimal_separator path are unaffected.
Comment thread price_parser/parser.py Outdated
Comment on lines +62 to +63
# The remaining "." or "," must be the decimal separator, since the
# caller declared the other symbol to be the digit group separator.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you remove this comment and instead update the docstring to reflect the new logic?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(That they won't is the main reason I close such PRs)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤞

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done — comment dropped, docstring now covers the inference. Sorry for the long delay.

@AdrianAtZyte
AdrianAtZyte requested a review from wRAR June 23, 2026 08:24
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (64e213a) to head (1e6e740).

Additional details and impacted files
@@             Coverage Diff             @@
##           master       #77      +/-   ##
===========================================
+ Coverage   98.23%   100.00%   +1.76%     
===========================================
  Files           3         3              
  Lines         113       115       +2     
  Branches       16        17       +1     
===========================================
+ Hits          111       115       +4     
+ Misses          1         0       -1     
+ Partials        1         0       -1     
Files with missing lines Coverage Δ
price_parser/parser.py 100.00% <100.00%> (+2.32%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AdrianAtZyte

Copy link
Copy Markdown
Contributor

Do you think you could complete test coverage based on the feedback from CodeCov?

@binggao1230

Copy link
Copy Markdown
Author

Added a test for the explicit-decimal-separator case (1e6e740) — the group-separator inference now has full branch coverage (patch 100%).

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.

3 participants