Change locale by creating wxLocale objects in wxpython 3.0.2.0

Mr&Mrs D <[email protected]> Tue, 15 Jan 2019 02:32:10 -0800 (PST)
Newsgroups gmane.comp.python.wxpython.devel
Message-ID <[email protected]>
Hi all :)

I posted on SO: https://stackoverflow.com/q/54178028/281545

You can reply to me there

Post:

I am maintaining a legacy python 2 app and I am trying to move from 
wxpython 2.8.12.1 to 3.0.2 - I get this assertion error:

     Traceback (most recent call last):
          File "Wrye Bash Launcher.pyw", line 88, in <module>
            bash.main()
          File "bash\bash.py", line 428, in main
            frame = app.Init() # Link.Frame is set here !
          File "bash\basher\__init__.py", line 4316, in Init
            size=settings['bash.frameSize'])
          File "bash\basher\__init__.py", line 3906, in __init__
            self.SetStatusBar(BashStatusBar(self))
          File "bash\basher\__init__.py", line 3669, in __init__
            self.UpdateIconSizes()
          File "bash\basher\__init__.py", line 3707, in UpdateIconSizes
            self._addButton(link)
          File "bash\basher\__init__.py", line 3681, in _addButton
            gButton = link.GetBitmapButton(self,style=wx.NO_BORDER)
          File "bash\basher\app_buttons.py", line 657, in GetBitmapButton
            image=staticBitmap(window, special='undo', size=(size,size)))
          File "bash\balt.py", line 509, in staticBitmap
            return bmp(wx.ART_UNDO,wx.ART_TOOLBAR,size)
          File "C:\_\Python27\lib\site-packages\wx-3.0-msw\wx\_misc.py", 
line 3013, in ArtProvider_GetBitmap
            return _misc_.ArtProvider_GetBitmap(*args, **kwargs)
        wx._core.PyAssertionError: C++ assertion "strcmp(setlocale(LC_ALL, 
NULL), "C") == 0" failed at ..\..\src\common\intl.cpp(1449) 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!



It says:

You probably called setlocale() directly instead of using wxLocale and now 
> there is a mismatch between C/C++ and Windows locale


(what is the Windows and what is the C/C++ locale btw?)

Well, this I did as in:

    #--Do translator test and set
    if locale.getlocale() == (None,None):
        locale.setlocale(locale.LC_ALL,u'')
    initTranslator(language)

In the docs of locale.setlocale 
<https://docs.python.org/2/library/locale.html#locale.setlocale> we read:

Applications typically start with a call of     
> import locale
> locale.setlocale(locale.LC_ALL, '')
> This sets the locale for all categories to the user’s default setting


Then in the program, locale-aware functions are defined all over as in 
<https://github.com/wrye-bash/wrye-bash/blob/b006164b51c5d1afce8b3059c46b7679bb3c02a5/Mopy/bash/bolt.py#L178-L181>

 def formatInteger(value):
    """Convert integer to string formatted to locale."""
    return decode(locale.format('%d', int(value), True),
                  locale.getpreferredencoding())


Omitting the call to `locale.setlocale` lets the program start but I don't 
believe these functions will do anything useful anymore (edit: confirmed).

There are similar questions as in 
https://stackoverflow.com/q/33505916/281545 but the solution suggested 
modify the locale of the `wx.App` while the setlocale call in my code is 
issued well before wx is even imported. People also use constructs as 
`wx.Locale(wx.LANGUAGE_ENGLISH)` but this is obviously a hack, I do not 
want to force user locale to english - for another hack see here 
<https://github.com/WikidPad/WikidPad/commit/625e0e6f0869b9ad6071fe0110886c75804971a5>

The `initTranslator` 
<https://github.com/wrye-bash/wrye-bash/blob/b006164b51c5d1afce8b3059c46b7679bb3c02a5/Mopy/bash/bolt.py#L338-L378> method 
above uses the standard `gettext` and `msgfmt` mechanism.

*QUESTION*

I need a standard *non hacky* way to replace the `locale.setlocale` call 
with the wx analog without breaking the translation and the locale aware 
parts of the program. I have this question for almost four years now and 
have found no canonical answer.

*EDIT*: omitting the setlocale call does not affect the translation (yey!) 
but does indeed break the locale aware displaying functions.

*EDIT2*: replacing the call above by:

    -    # if locale.getlocale() == (None,None):
    -    #     locale.setlocale(locale.LC_ALL,u'')
    +    if locale.getlocale() == (None,None):
    +        # locale.setlocale(locale.LC_ALL,u'')
    +        import wx
    +        wx.Locale(wx.LANGUAGE_DEFAULT)
         if not lang:

results in a bunch of warnings:

   
 7:12:22 AM: Debug: ..\..\src\common\stdpbase.cpp(56): assert "traits" 
failed in wxStandardPathsBase::Get(): create wxApp before calling this
    7:12:41 AM: Debug: ..\..\src\common\stdpbase.cpp(56): assert "traits" 
failed in wxStandardPathsBase::Get(): create wxApp before calling this
    7:12:42 AM: Debug: ..\..\src\common\stdpbase.cpp(56): assert "traits" 
failed in wxStandardPathsBase::Get(): create wxApp before calling this
    7:12:42 AM: Debug: ..\..\src\common\platinfo.cpp(171): assert 
"wxAssertFailure" failed in wxPlatformInfo::InitForCurrentPlatform(): 
failed to initialize wxPlatformInfo
    7:12:52 AM: Debug: ..\..\src\common\platinfo.cpp(109): assert "value" 
failed in wxGetIndexFromEnumValue(): invalid enum value
    7:13:12 AM: Debug: ..\..\src\common\platinfo.cpp(240): assert "idx < 
(sizeof(wxPortIdNames)/sizeof(wxPortIdNames[0]))" failed in wxPlatformInfo::
GetPortIdName(): invalid port id


So so I have to create the wx.App (I would really like to avoid this as I 
want to be able to translate (possibly fatal) error messages long before 
wx.App is created)

-- 
You received this message because you are subscribed to the Google Groups "wxPython-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.