Skip to content

DM_UNIX_TIME serialization changes the caller numeric locale #252

Closed

Description

@parijat1222q

Serializing a date or datetime with DM_UNIX_TIME changes the process-wide numeric locale to C on Linux, even though the JSON encoder is not supposed to change the caller's locale.

Reproduced on current master (fcf6dd65d04cb75ebf52582e7ba23a49a8b7dd10), CPython 3.14.8 / glibc Linux:

import locale
from datetime import datetime, timezone
import rapidjson

locale.setlocale(locale.LC_NUMERIC, "de_DE.UTF-8")
before = locale.setlocale(locale.LC_NUMERIC)
print(locale.format_string("%.1f", 1.5))  # 1,5
print(rapidjson.dumps(
    datetime(2026, 10, 26, 1, 2, 3, 123456, tzinfo=timezone.utc),
    datetime_mode=rapidjson.DM_UNIX_TIME,
))  # 1792976523.123456
print(before, locale.setlocale(locale.LC_NUMERIC))  # de_DE.UTF-8 C
print(locale.format_string("%.1f", 1.5))  # 1.5

date values with DM_UNIX_TIME | DM_NAIVE_IS_UTC have the same effect. I reproduced it across dumps, text/binary dump, and the corresponding Encoder routes.

Both timestamp-formatting blocks save the pointer returned by setlocale(LC_NUMERIC, NULL), switch to C, and later use the saved pointer to restore the original locale. That pointer can be overwritten or invalidated by the next setlocale call. Restoring through it therefore does not preserve the caller's locale.

Expected: JSON still uses a decimal point, and LC_NUMERIC and unrelated locale-aware number formatting remain unchanged.

I have a fix using CPython's locale-independent PyOS_double_to_string with the existing six-decimal formatting and trailing-zero handling, so no process-wide locale switch is needed. The regression tests fail in all 12 comma-locale cases on master and pass with the fix; 12 C-locale controls also pass.

Activity

  1. lelit commented on Oct 26, 2026

    @lelit
    Contributor

    Thanks for the report!

  2. parijat1222q commented on Oct 26, 2026

    @parijat1222q
    ContributorAuthor

    @lelit CI checks are passed

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions