Tk Source Code

View Ticket
Login
2026-09-22
15:11 • Closed ticket [9e89324a]: spinbox parses its value with sscanf("%lf"), which depends on the LC_NUMERIC locale plus 9 other changes artifact: 1c31feb1 user: jan.nijtmans
2026-09-20
17:53 • Ticket [2112563f] Tk is not safe against extensions that call setlocale(). status still Open with 3 other changes artifact: 844a6611 user: serhiy.storchaka
2026-09-17
09:53 • Ticket [348b482f] scale, spinbox and place format floating-point values using the LC_NUMERIC locale, producing non-numeric strings (e.g. "0,3") status still Closed with 3 other changes artifact: fcd401d3 user: serhiy.storchaka
2026-06-30
13:37
Fix [348b482ff7]: scale, spinbox and place format floating-point values using the LC_NUMERIC locale check-in: b05d042d user: jan.nijtmans tags: core-8-6-branch
09:10 • Ticket [348b482f] scale, spinbox and place format floating-point values using the LC_NUMERIC locale, producing non-numeric strings (e.g. "0,3") status still Closed with 2 other changes artifact: 737669e7 user: serhiy.storchaka
2026-06-29
08:20 • Ticket [348b482f]: 6 changes artifact: 383cd2f3 user: oehhar
2026-06-25
12:46 • Ticket [348b482f]: 5 changes artifact: b34324e3 user: jan.nijtmans
12:08 • Ticket [348b482f]: 6 changes artifact: f45de4ff user: oehhar
09:19 • Ticket [348b482f]: 5 changes artifact: e908f804 user: jan.nijtmans
09:08
Follow-up to [348b482ff7]. Three more places where TkFormatDouble should have been used check-in: 88296c07 user: jan.nijtmans tags: trunk, main
08:44
Follow-up to [348b482ff7]. Two more places where TkFormatDouble should have been used check-in: bc8c7390 user: jan.nijtmans tags: core-9-0-branch
07:30 • Ticket [348b482f] scale, spinbox and place format floating-point values using the LC_NUMERIC locale, producing non-numeric strings (e.g. "0,3") status still Closed with 5 other changes artifact: 9faa9810 user: serhiy.storchaka
2026-06-24
14:59 • Ticket [348b482f]: 4 changes artifact: 0fa645c6 user: jan.nijtmans
14:56
Extend fix for [348b482ff7]. Not sufficiently tested yet closed check-in: 42255c8b user: jan.nijtmans tags: bug-348b482ff7
12:16 • Closed ticket [348b482f]: scale, spinbox and place format floating-point values using the LC_NUMERIC locale, producing non-numeric strings (e.g. "0,3") plus 7 other changes artifact: dc0a4964 user: jan.nijtmans
11:57
Fix [348b482ff7]: scale, spinbox and place format floating-point values using the LC_NUMERIC locale check-in: 23f641b0 user: jan.nijtmans tags: trunk, main
11:31
Fix [348b482ff7]: scale, spinbox and place format floating-point values using the LC_NUMERIC locale check-in: eecd0f37 user: jan.nijtmans tags: core-9-0-branch
09:36 • Ticket [348b482f] scale, spinbox and place format floating-point values using the LC_NUMERIC locale, producing non-numeric strings (e.g. "0,3") status still Open with 3 other changes artifact: b2e083af user: serhiy.storchaka
09:29 • Add attachment tk86-lcnumeric-fix.patch to ticket [348b482f] artifact: f034b62d user: serhiy.storchaka
09:26 • Add attachment tk-lcnumeric-fix.patch to ticket [348b482f] artifact: fb801a51 user: serhiy.storchaka
09:20 • New ticket [348b482f] scale, spinbox and place format floating-point values using the LC_NUMERIC locale, producing non-numeric strings (e.g. "0,3"). artifact: 11ca0207 user: serhiy.storchaka

Ticket UUID: 348b482ff73ea18b385070a9a4bb60028c32ad1a
Title: scale, spinbox and place format floating-point values using the LC_NUMERIC locale, producing non-numeric strings (e.g. "0,3")
Type: Bug Version: 8.6, 8.7, 9.0, 9.1b0
Submitter: serhiy.storchaka Created on: 2026-06-24 09:20:43
Subsystem: (unused) Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Important
Status: Closed Last Modified: 2026-09-17 09:53:28
Resolution: Fixed Closed By: oehhar
    Closed on: 2026-06-29 08:20:03
Description:

scale, spinbox and place format floating-point values with the C library's locale-sensitive conversions (snprintf("%g"), Tcl_ObjPrintf("%g")), which honour LC_NUMERIC. Under a locale that uses , as the decimal separator they produce strings like "0,3" — but these values go into linked -variables, subcommand results, -command callbacks and place info, where a valid Tcl number is required. "0,3" does not parse:

expected floating-point number but got "0,3"

Tk's number parsing is already locale-independent (Tcl_GetDoubleFromObj; strtod removed in 8.7), so only formatting is affected — a value Tk writes can no longer be read back by Tk.

Affected sites: scale -variable/get/-command (tkScale.c, tkUnixScale.c); spinbox value on step/-format (tkEntry.c); place info -relx/-rely/ -relwidth/-relheight (tkPlace.c).

Reproducing

LC_NUMERIC must be a comma locale while the widget runs. Tcl resets it to "C" at init, so plain tclsh/wish is unaffected; an embedder that calls setlocale(LC_NUMERIC, ...) afterwards triggers it — e.g. a Python program doing locale.setlocale(locale.LC_NUMERIC, "de_DE.UTF-8") before using tkinter.

setlocale(LC_NUMERIC, "de_DE.UTF-8");   /* after Tcl_Init/Tk_Init */
spinbox .s -from 0 -to 1 -increment 0.1 -textvariable v; .s set 0; .s invoke buttonup
scale .sc -from 0 -to 1 -resolution 0.1 -variable w; .sc set 0.3
frame .f; place .f -relx 0.3 -rely 0.6

Observed (9.1b0): v=0,1 w=0,3 [.sc get]=0,3 [place info .f] ... -relx 0,3 ... and expr {$v + 0} raises the error above. Expected: v=0.1 w=0.3 0.3 ... -relx 0.3 ...

Root cause and fix

Tcl numbers always use . (Tcl_PrintDouble, Tcl_GetDoubleFromObj); these widgets bypass that and call the C library, so output follows LC_NUMERIC.

The attached patch adds a helper

int TkFormatDouble(char *buffer, size_t size, const char *format, double value);

that does the snprintf() and, when localeconv()->decimal_point is a single-byte separator other than ., replaces it (a %f/%e/%g conversion emits at most one). The widget value conversions are routed through it. 6 files (tkUtil.c + tkInt.h, tkScale.c, tkEntry.c, tkPlace.c, tkUnixScale.c), +94/-19. unix/tkUnixScale.c is the scale display file compiled on all platforms (win/Makefile.in and the Aqua build both use it), so there is no separate macOS/Windows source.

With the patch the reproducer gives the expected output in any locale, the "C" locale is unchanged, and scale/place/spinbox/entry tests pass (the locally seen entry-3.1 bbox failure is font/display dependent and fails identically without the patch).

Notes

  • 8.6 backport: ported and verified the same way; identical sites, only Tcl_NewStringObj(s, -1) instead of ... TCL_INDEX_NONE. Separate patch on request. (8.6 also still has the parsing bug — "bad screen distance" via strtod — fixed in 8.7; out of scope here.)
  • Open question: the patch makes these widgets render . in every locale (matching the default "C" behaviour). If display should instead show the localized separator while only machine-readable values stay ., drop the tkUnixScale.c drawing hunks; the rest still fixes the round-trip.

Downstream

User Comments: serhiy.storchaka added on 2026-09-17 09:53:28:
Verified on main and core-8-6-branch with setlocale(LC_NUMERIC, "de_DE.utf8") called after Tk_Init: spinbox, scale, place and ttk::spinbox now produce values with "." that parse again. Thanks!

added on 2026-06-30 09:10:11:

ttk::spinbox is not covered by this fix: it formats its value in script with [format $fmt $val], and Tcl's format itself honours LC_NUMERIC. Tracked separately as https://core.tcl-lang.org/tcl/tktview/fcd3dadd79cf.


oehhar added on 2026-06-29 08:20:03:

Serhy, about 8.6. That is on personal initiative. If you want commit rights to do it, just give a sign.

Thanks for all, Harald


jan.nijtmans added on 2026-06-25 12:46:40:

> Numbers might also contain thousends separator

I tried to find instances in Tcl and Tk to create a thousends separator. Didn't find any. Therefore I didn't merge that part of my modification.


oehhar added on 2026-06-25 12:08:30:

Serhiy, would be great if you could verify if the solution by Jan is effective for you. THanks for all, Harald


jan.nijtmans added on 2026-06-25 09:19:48:

8.6 is end-of-life now. Sorry.

Found 3 more (2 in 9.0) places where TkFormatDouble() should be used. Fixed that now too.


serhiy.storchaka added on 2026-06-25 07:30:33:
Thank you. What about 8.6?

jan.nijtmans added on 2026-06-24 14:59:54:

Let's extend that a little bit: [42255c8bd65a3d69].

Explanation: Numbers might also contain thousends separator, Tcl only recognises '_'. Didn't test this yet, but might be possible for scaler tickmarks.

Also found 2 more places where TkFormatDouble() should be used.

Not tested sufficiently yet.....


jan.nijtmans added on 2026-06-24 12:16:11:

Fixed [23f641b03c72e50a|here] (and in core-9-0-branch too)

I like this solution. Thanks!


Attachments: