wxWidgets / Phoenix

wxPython's Project Phoenix. A new implementation of wxPython, better, stronger, faster than he was before.
http://wxpython.org/
2.33k stars 515 forks source link

wxLocale::GetInfo(): vs setlocale() on Win10 with funny locales #1751

Open microphysics opened 4 years ago

microphysics commented 4 years ago

Operating system: Win10 wxPython version & source: 4.1.1a1.dev4892+33fa9afd pip [...] https://wxpython.org/Phoenix/snapshot-builds/ Python version & source: 3.8.5 stock

Description of the problem: I'm trying to run "cockpit" on a Win10 machine and keep getting an error: wxLocale::GetInfo(): You probably called setlocale() directly instead of using wxLocale and now there is a mismatch between C/C++ and Windows locale. Issue in the cockpit-project: https://github.com/MicronOxford/cockpit/issues/658

import wx

path_to_some_png = '/tmp/foo.png'

app = wx.App()
bitmap = wx.Bitmap(path_to_some_png, wx.BITMAP_TYPE_ANY)
frame = wx.Frame(None)
frame.Show()
app.MainLoop()

additional Info:

import locale
print('default is ', locale.getdefaultlocale())
print('locale is ', locale.getlocale())

default is ('en_DE', 'cp1252') locale is ('English_Germany', '1252')

ricpol commented 4 years ago

see https://discuss.wxpython.org/t/a-few-more-windows-locale-related-remarks/34788 for a bit of context about this problem. You can try the new wx.App.InitLocale implementation, or maybe override wx.App.InitLocale... but I doubt it's really a wxPython issue. This could be due to a Python 3.8 hidden api change: see https://bugs.python.org/issue38805#msg373896 for details.

carandraug commented 4 years ago

[...] You can try the new wx.App.InitLocale implementation, or maybe override wx.App.InitLocale [...]

If you mean this:

    def InitLocale(self):
        self.ResetLocale()
        if 'wxMSW' in wx.PlatformInfo:
            import locale
            try:
                lang, enc = locale.getdefaultlocale()
                self._initial_locale = wx.Locale(lang, lang[:2], lang)
                locale.setlocale(locale.LC_ALL, lang)
            except (ValueError, locale.Error) as ex:
                target = wx.LogStderr()
                orig = wx.Log.SetActiveTarget(target)
                wx.LogError("Unable to set default locale: '{}'".format(ex))
                wx.Log.SetActiveTarget(orig)

We already tried to override it but the problem remains.

ricpol commented 4 years ago

Yes. As I try to explain in my little essays (linked above), perhaps you should look into how Python 3.8 now sets a locale at startup (in windows) and how this new, almost undocumented behaviour afflicts your application. As for InitLocale, I think it can help, but only up to a point (again, as I try to explain in the article linked above). I am not quite sure about nothing here, as I didn't dig myself into the cockpit source code... I'm just saying, I would recommend to consider this new python 3.8 behaviour, before looking at possible wxPython bugs. Besides, wxPython does not tamper with locale settings, other than the little InitLocale trick. So, if you override InitLocale and make it a noop, you can just remove wxPython from the equation.

carandraug commented 4 years ago

Cockpit doesn't handle locale directly, which is why this seemed liked a wxPython problem. I will see about overriding InitLocale with a no op.

ricpol commented 4 years ago

Cockpit doesn't handle locale directly

Sure it does, at the very least since it runs a wx.App instance :-)

Anyways, unfortunately I cannot investigate this further, for the very basic reason that "pip install microscope-cockpit" will not work. So, lacking a clean way to install cockpit, I can't reproduce this bug. As far as I can tell from the original stacktrace, it seems to me like cockpit is hitting a libpng issue that can be probably fixed by a little png cleanup. However, I can't say for sure. I would advise to insert a good old-fashioned "print" here to find out exactly which png is loading when it crashes. In addition, if the problem occurs only in python 3.8 but not 3.7, then I refer you to what I have already written about it.

If nothing of this works, or even makes any sense at all... well at least I tried :-) This is an issue with cockpit in the first place. If you can produce a cockpit-free, wxpython-only code snippet that presents the same behaviour, then it will easier to investigate from the wxpython side.

jurneo commented 3 years ago

I am sharing the work around found from the other forum for those who look for a quick solution https://discuss.wxpython.org/t/wxpython4-1-1-python3-8-locale-wxassertionerror/35168

import locale
locale.setlocale(locale.LC_ALL,'C')