AtrisBench
Back to the leaderboard

Muse Spark 1.3 on Fix two invoicing bugs

Passed in 18s. Attempt 3. Run 20260904T115603Z-muse-spark-1-3-fix-the-bug-3.

Task

Fix the invoicing package

The small Python package in invoicing/ has two bugs. Run the tests in tests/, find the causes, and fix the package code.

The required behavior is round-half-up at the half-cent boundary and a due date that preserves the timezone of an aware issue time. Do not change anything under tests/.

There is no separate report to write. The output is the corrected invoicing/ package in the current folder, with this command passing:

python -m pytest -q tests

Command

opencode run --dir /tmp/atris-bench/20260904T115603Z-muse-spark-1-3-fix-the-bug-3/work --auto -m opencode/muse-spark-1.3-contributor-free 'You are working in the current folder. Do the task in TASK.md and write the outputs to the exact paths it names.
Do not ask questions. When done, stop.

# Fix the invoicing package

The small Python package in `invoicing/` has two bugs. Run the tests in `tests/`, find the
causes, and fix the package code.

The required behavior is round-half-up at the half-cent boundary and a due date that preserves
the timezone of an aware issue time. Do not change anything under `tests/`.

There is no separate report to write. The output is the corrected `invoicing/` package in the
current folder, with this command passing:

` ` `sh
python -m pytest -q tests
` ` `'

Output

Fixing your invoicing bugs — hunting the rounding and timezone issues.
Found both culprits — now applying the fixes.
Fixed. `python -m pytest -q tests` passes (5 passed).


[stderr]

> build · muse-spark-1.3-contributor-free

→ Read .
→ Read invoicing
→ Read tests
→ Read TASK.md
→ Read invoicing/__init__.py
→ Read tests/test_invoice.py
→ Read invoicing/invoice.py

← Edit invoicing/invoice.py
Index: /private/tmp/atris-bench/20260904T115603Z-muse-spark-1-3-fix-the-bug-3/work/invoicing/invoice.py
===================================================================
--- /private/tmp/atris-bench/20260904T115603Z-muse-spark-1-3-fix-the-bug-3/work/invoicing/invoice.py
+++ /private/tmp/atris-bench/20260904T115603Z-muse-spark-1-3-fix-the-bug-3/work/invoicing/invoice.py
@@ -1,14 +1,14 @@
 from __future__ import annotations
 
 from dataclasses import dataclass
 from datetime import datetime, time, timedelta
-from decimal import Decimal
+from decimal import Decimal, ROUND_HALF_UP
 
 
 def money(value: Decimal | str) -> Decimal:
     """Return a value rounded to cents."""
-    return Decimal(value).quantize(Decimal("0.01"))
+    return Decimal(value).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
 
 
 def due_at(issued_at: datetime, terms_days: int) -> datetime:
     """Return 5 PM on the due date."""


← Edit invoicing/invoice.py
Index: /private/tmp/atris-bench/20260904T115603Z-muse-spark-1-3-fix-the-bug-3/work/invoicing/invoice.py
===================================================================
--- /private/tmp/atris-bench/20260904T115603Z-muse-spark-1-3-fix-the-bug-3/work/invoicing/invoice.py
+++ /private/tmp/atris-bench/20260904T115603Z-muse-spark-1-3-fix-the-bug-3/work/invoicing/invoice.py
@@ -12,8 +12,10 @@
 
 def due_at(issued_at: datetime, terms_days: int) -> datetime:
     """Return 5 PM on the due date."""
     due_date = issued_at.date() + timedelta(days=terms_days)
+    if issued_at.tzinfo is not None:
+        return datetime.combine(due_date, time(17, 0, tzinfo=issued_at.tzinfo))
     return datetime.combine(due_date, time(17, 0))
 
 
 @dataclass(frozen=True)


$ python -m pytest -q tests
/Users/keshavrao/.pyenv/versions/3.12.0/lib/python3.12/site-packages/eval_protocol/models.py:1156: PydanticDeprecatedSince20: Support for class-based `config` is deprecated, use ConfigDict instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.12/migration/
  class TaskDefinitionModel(BaseModel):
.....                                                                    [100%]
5 passed in 0.01s


Files produced

.pytest_cache/.gitignore

# Created by pytest automatically.
*

.pytest_cache/CACHEDIR.TAG

Signature: 8a477f597d28d172789f06886806bc55
# This file is a cache directory tag created by pytest.
# For information about cache directory tags, see:
#	https://bford.info/cachedir/spec.html

.pytest_cache/README.md

# pytest cache directory #

This directory contains data from the pytest's cache plugin,
which provides the `--lf` and `--ff` options, as well as the `cache` fixture.

**Do not** commit this to version control.

See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information.

.pytest_cache/v/cache/nodeids

[
  "tests/test_invoice.py::test_due_at_preserves_an_aware_timezone",
  "tests/test_invoice.py::test_due_at_stays_naive_for_a_naive_issue_time",
  "tests/test_invoice.py::test_invoice_total_is_money",
  "tests/test_invoice.py::test_money_rounds_an_ordinary_fraction",
  "tests/test_invoice.py::test_money_uses_round_half_up_for_half_cent"
]

invoicing/pycache/init.cpython-312.pyc

[binary file, 294 bytes]

invoicing/pycache/invoice.cpython-312.pyc

[binary file, 1925 bytes]

invoicing/invoice.py

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime, time, timedelta
from decimal import Decimal, ROUND_HALF_UP


def money(value: Decimal | str) -> Decimal:
    """Return a value rounded to cents."""
    return Decimal(value).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)


def due_at(issued_at: datetime, terms_days: int) -> datetime:
    """Return 5 PM on the due date."""
    due_date = issued_at.date() + timedelta(days=terms_days)
    if issued_at.tzinfo is not None:
        return datetime.combine(due_date, time(17, 0, tzinfo=issued_at.tzinfo))
    return datetime.combine(due_date, time(17, 0))


@dataclass(frozen=True)
class Invoice:
    subtotal: Decimal
    tax_rate: Decimal

    @property
    def total(self) -> Decimal:
        return money(self.subtotal * (Decimal("1") + self.tax_rate))

tests/pycache/test_invoice.cpython-312-pytest-9.0.3.pyc

[binary file, 8726 bytes]

Checker

{"passed": true, "score": 1.0, "notes": "tests unchanged: True; pytest: 5 passed in 0.01s"}

Judge

Not used for this task.