On Windows 10, wxPython 4.1.1, Python 3.8
Getting the following error when trying to initialize image bmp = wx.Image(“image.png”)
File "app.py", line 628, in __init__
wx._core.wxAssertionError: C++ assertion "strcmp(setlocale(0, 0), "C") == 0" failed at ..\..\src\common\intl.cpp(1694) in wxLocale::GetInfo(): You probably called setlocale() directly instead of using wxLocale and now there is a mismatch between C/C++ and Windows locale.
Things are going to break, please only change locale by creating wxLocale objects to avoid this!
This is only happening with windows Region = “Spanish (Latin America)”
Changing to “Spanish Mexico” fixes the issue.
In fact, what I noticed is that the issue only happens when Windows Region language is set to a language that doesn’t exit in wxWidgets: interface/wx/language.h File Reference
So, “Spanish (Dominican Republic)” works, but “Spanish (Cuba)” doesn’t. Ecuador works, Equatorial Guinea doesn’t.
Setting the locale during the initialization like below
class MyApp(wx.App):
def OnInit(self):
self.locale = wx.Locale(wx.LANGUAGE_DEFAULT)
causes another problem - it breaks all the “standard” (non-wx) python functions that are using standard locale (such as datetime.strptime
for example). Basically those functions are failing with ValueError: unknown locale: en-US
due to the fact that wxPython seems to follow “windows way” in setting the locale and is using “-” hyphen in the locale name. The “sandard” python functions are using “linux way” with “_” underscore in the locale name.
The only (ugly and hacky) workaround that I found looks like this:
- On startup, override the python locale to “C” locale. Interestingly, this step is only required in Python 3.8 (python 3.7 is already returning locale (None, None) on startup)
import locale
locale.setlocale(locale.LC_ALL,'C')
- Then in wx.App, override the InitLocale to prevent wxPython from setting the locale in “windows way”. This is only required with wxPython4.1.1 (4.0.4 works without it, apparently it doesn’t try to initialize the locale in any way and it remains “c” locale).
def InitLocale(self):
self.ResetLocale()
Is there anything I’m missing? As mentioned, issue is only happening with certain language settings.
The full code to reproduce
import wx
import locale
class mainFrame(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self,parent,-1,"title")
bmp = wx.Image("image.png") # this will fail if win locale is Spanish Latin America
print('locale during: %s'% (locale.getlocale(),)) # this will fail with ValueError if you try to initialize wx.Locale in the wx.app OnInit
class MyApp(wx.App):
def OnInit(self):
w = mainFrame(None)
w.Show()
return True
def main():
app = MyApp(False)
app.MainLoop()
if __name__ == '__main__':
main()