In case of en-US, the problem is that it is an invalid locale identifier reported by Windows (en_US being the valid id). In Rhino, when editor is launched I check against this case and a few others and correct them automatically:
After launching Rhino, run RhinoCodeLogs command and look for messages like this:
Info 18/3/2024 20:42:26 [RhinoCode] Python default locale is 'en_ZW.cp1252'
Info 18/3/2024 20:42:26 [RhinoCode] Python current locale is 'English_Zimbabwe.1252'
or
Info 18/3/2024 20:42:26 [RhinoCode] updated local from 'en-US' to 'en_US'
Q: Would you mind confirming this correction is happening on your machine and is reported in the logs?
Here is how importing pandas look like on my machine:
Ehsan that’s an excellent spot - well done. In most Pythons this can be verified via:
Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> for code in ('en_US', 'en-US.UTF8', 'en-US'):
... print(locale._parse_localename(code))
...
('en_US', 'ISO8859-1')
('en-US', 'UTF8')
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "C:\Users\...\AppData\Local\Programs\Python\Python39\lib\locale.py", line 501, in _parse_localename
raise ValueError('unknown locale: %s' % localename)
ValueError: unknown locale: en-US
However I’m not sure it’s the full story. The question is what’s setting the locale "en-US" to contain a hyphen in the first place. I haven’t been able to find this hyphenated locale name in any other application in Windows, other than Rhino 8’s CPython, and even then only within Grasshopper. So perhaps the root cause is, that something, either in Rhino, or in the integration of Python 3.9 within Rhino 8, is setting that locale code to "en-US". I can’t reproduce the error in Python 2.7 components within Grasshopper, so I suspect it’s not Rhino.
From the command line (both a standard 3.9 from python.org and Rhino 8’s own Python 3.9):
During pandas rather complicated initial import, it imports _strptime, a core library of Python’s (even though it starts with an underscore):
Within Python 3.9’s _strptime.py, a default instance of TimeRE is created.
If TimeRE.__init__ is called with no args, an instance of LocaleTime is created. LocaleTime.__init__ calls _getlang, (which I’ve used in the tests above, now realise I didn’t actually need to, as importing the module calls it anyway).
The rogue hyphenated “en-US” comes from the _locale module. Without that, Python defaults to the C locale. The user facing locale imports setlocale from _locale. This _locale module (I can’t find its source as it’s probably compiled or even buried in a dll) behaves differently in Rhino 8’s Python 3 from the command line, as it does within Rhino 8.
>.\python.exe -c "import _locale; print(_locale.setlocale(5))"
C
The 5 is local.LC_TIME
>py -3.9 -c "import _locale; print(_locale.setlocale(5))"
So, Microsoft and Rhino have done this right in the modern way! I wonder if Python 3.9 followed Posix and C idioms (as well as its own historical ones), and contained a bug that crops up in this edge case.
ISO_3166-1 doesn’t care, but to be compliant with RFC1766 Lang/ Country/ lang codes should be separated by hyphens:
Python does normalize the language/country tags in locale.setlocale:
but only crudely by testing the string against a huge hardcoded dict of lang codes, in which all the entries are separated by underscores, not hyphens: