Skip to content

Fix math.log argument checks for zero, None base and order - #1264

Open
jseop-lim wants to merge 2 commits into
oracle:masterfrom
jseop-lim:fix/math-log
Open

jseop-lim wants to merge 2 commits into
oracle:masterfrom
jseop-lim:fix/math-log

Conversation

@jseop-lim

@jseop-lim jseop-lim commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Description

Fixes #1253

LogNode had three gaps in its argument checks. The specializations that take a base tested the value with < 0, so a zero value returned -inf. The one-argument specializations took the base as an unguarded PNone, so None was treated as a missing base. The specializations for a non-number base converted it before the value was checked. CPython's math_log computes log(x) first, rejecting any x <= 0, and only then converts the second argument, whatever it is (mathmodule.c#L2269-L2273).

AS-IS

>>> math.log(0, 2)
-inf
>>> math.log(10, None)
2.302585092994046
>>> math.log(-1, object())
TypeError: must be real number, not object

TO-BE

>>> math.log(0, 2)
ValueError: math domain error
>>> math.log(10, None)
TypeError: must be real number, not NoneType
>>> math.log(-1, object())
ValueError: math domain error

(matching CPython)

Changes

  • Reject a zero value with <= 0 in logPIN, logDD, logDPI, logPID, logLPI and logPIPI, as logDN already does.
  • Guard log(long, PNone), logDN, logPIN and logO with isNoValue(novalue), so None goes to the specializations that convert the base.
  • Check the value's domain in logOO, logLO, logDO and logPIO before converting the base, and add !isNoValue(base) to logLO, logDO and logPIO, as logOO has. Without that guard, once a None base had activated one of them, a later math.log(10) was dispatched there and raised TypeError.
  • Add tests/test_math_log.py.

Testing

mx python-jvm on darwin-aarch64, then mx graalpytest test_math_log.py (3 passed) and test_math.py (61 passed), and test.test_math from lib-python with --tagged (79 passed). The new tests fail on the unpatched build (2 failures, 1 error). 25 math.log call shapes, covering int subclasses, None, object() and __float__ arguments, now print the same as CPython 3.13.14, except for a last-digit difference in math.log(8.0, 2**70) that master has too.

Three defects in LogNode:

- A zero value passed the two-argument domain checks, which tested
  value < 0, so math.log(0, 2) returned -inf.
- The one-argument specializations took any PNone, so an explicit
  base of None was treated as omitted and math.log(10, None) returned
  the natural logarithm.
- The specializations for a non-number base converted the base before
  checking the value, so math.log(-1, object()) raised TypeError.

CPython checks the value, then converts the base, and raises
ValueError for any value <= 0.

Signed-off-by: Jeongseop Lim <jeongseop_lim@korea.ac.kr>
logPIO also needs the missing-base guard; assert that math.log on a
large int still works after math.log(2**70, None).

Signed-off-by: Jeongseop Lim <jeongseop_lim@korea.ac.kr>
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Oct 31, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

1 participant