Python 有哪些策略可确保在所有区域设置中正确处理所有区域设置感知操作?

Python 有哪些策略可确保在所有区域设置中正确处理所有区域设置感知操作?,python,c,unit-testing,testing,locale,Python,C,Unit Testing,Testing,Locale,出于某种需要,我开发的软件将语言环境设置为“C”或“en_US”。使用不同的语言环境是很困难的,因为我只会说一种语言,甚至有一点接近流利 因此,我经常忽略不同区域设置可能带来的行为差异。毫不奇怪,忽略这些差异有时会导致错误,而这些错误只能由使用不同区域设置的不幸用户发现。在特别糟糕的情况下,该用户甚至可能不会与我共享一种语言,这使得bug报告过程成为一个具有挑战性的过程。而且,重要的是,,我的很多软件都是以库的形式出现的;虽然几乎没有设置语言环境,但它可以与另一个库结合使用,或者用于设置了我从未

出于某种需要,我开发的软件将语言环境设置为“C”或“en_US”。使用不同的语言环境是很困难的,因为我只会说一种语言,甚至有一点接近流利

因此,我经常忽略不同区域设置可能带来的行为差异。毫不奇怪,忽略这些差异有时会导致错误,而这些错误只能由使用不同区域设置的不幸用户发现。在特别糟糕的情况下,该用户甚至可能不会与我共享一种语言,这使得bug报告过程成为一个具有挑战性的过程。而且,重要的是,,我的很多软件都是以库的形式出现的;虽然几乎没有设置语言环境,但它可以与另一个库结合使用,或者用于设置了我从未体验过的语言环境生成行为的应用程序中

更具体地说,我想到的各种bug不是缺少文本本地化,也不是使用这些本地化的代码中的bug。相反,我指的是当使用某个区域设置的API的代码没有预料到这种更改的可能性时(例如,在土耳其区域设置中,
toupper
没有将“I”更改为“I”,而该区域设置更改了某个区域设置感知API的结果(例如,
toupper(3)
)的bug-可能是网络服务器试图与另一台主机使用特定网络协议时出现的问题)

我维护的软件中的一些此类错误示例:

在过去,我处理这个问题的一种方法是编写回归测试,将区域设置显式更改为已知代码不起作用的区域设置,执行代码,验证正确的行为,然后恢复原始区域设置。这已经足够好了,但是只有在有人报告了一个bug之后,并且它只覆盖了代码库的一小部分

另一种可能的方法是设置连续集成系统(CIS),以便在具有不同语言环境集的环境中运行全套测试。这在某种程度上改善了这种情况,因为它在一个备用语言环境中提供了与测试套件通常提供的相同的覆盖率。另一个缺点是有很多很多地方,每个地方都可能导致不同的问题。在实践中,一个地区可能只有十几种不同的方法可以破坏一个程序,但是有几十种额外的测试配置会对资源造成负担(特别是对于一个已经通过在不同平台上测试、针对不同库版本等来扩展其资源限制的项目)

我想到的另一个方法是使用(可能首先创建)一个新的区域设置,它在各个方面都与“C”区域设置完全不同-具有不同的大小写映射,使用不同的千分位分隔符,以不同的格式设置日期,等。此区域设置可以与一个额外的CIS配置一起使用,并有望捕获任何区域设置可能触发的代码中的任何错误

这样的测试区域设置是否已经存在?这种测试语言环境兼容性的想法是否存在缺陷

人们还采取了哪些其他的现场测试方法


我主要对POSIX语言环境感兴趣,因为我知道这些语言环境。但是,我知道Windows也有一些类似的功能,因此额外的信息(可能包括关于这些功能如何工作的更多背景信息)可能也很有用。

我只想检查您的代码是否使用了不正确的函数,如
toupper
。在C语言环境模型下,此类函数应被视为仅对语言环境语言中的自然语言文本进行操作。对于任何处理潜在多语言文本的应用程序,这意味着根本不应使用诸如
tolower
之类的函数

如果您的目标是POSIX,那么由于使用了
uselocale
函数,您可以在单个线程中临时覆盖区域设置(即,在不破坏程序全局状态的情况下)。然后,您可以全局保留C语言环境,并对ASCII/面向机器的文本(如配置文件等)使用
tolower
等,并且在使用来自所述语言环境的自然语言文本时,仅对用户选择的语言环境使用
uselocale

否则(甚至如果您需要更高级的代码),我认为最好的解决方案是完全抛弃像
tolower
这样的函数,为配置文本等编写自己的ASCII版本,并为自然语言文本使用强大的支持Unicode的库


我还没有提到的一个棘手问题是与函数相关的小数分隔符,如
snprintf
strod
。在某些语言环境中,将其更改为
而不是
,可能会破坏您使用C库解析文件的能力。我的首选解决方案是永远不要设置
LC\u NUMERIC
locale。(我是一名数学家,所以我倾向于相信数字应该是通用的,不受文化习俗的约束。)根据您的应用,真正需要的语言环境类别可能只是
LC\u CTYPE
LC\u COLLATE
LC\u MESSAGES
。同样有用的还有
LC\u MONETARY
LC\u TIME

您需要解决两个不同的问题来回答您的问题:测试您的代码和与其他人处理代码问题

测试您自己的代码-我通过在CI环境中使用2或3个基于英语的区域设置来解决这个问题:en_GB(排序规则),en_ZW(几乎所有内容都会更改,但您仍然可以读取错误),然后en_AU(日期,排序规则)

如果您想确保您的代码使用多字节文件名,那么