Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-langtable for 
openSUSE:Factory checked in at 2024-07-08 19:07:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-langtable (Old)
 and      /work/SRC/openSUSE:Factory/.python-langtable.new.2080 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-langtable"

Mon Jul  8 19:07:05 2024 rev:12 rq:1186047 version:0.0.67

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-langtable/python-langtable.changes        
2024-06-06 12:31:49.938754886 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-langtable.new.2080/python-langtable.changes  
    2024-07-08 19:07:23.868847613 +0200
@@ -1,0 +2,15 @@
+Sun Jun 30 20:36:08 UTC 2024 - Dirk Müller <[email protected]>
+
+- update to 0.0.67:
+  * Add tool to check which languages, scripts, and territories
+    available in CLDR are missing in langtable
+  * Add all missing scripts and languages: yrl, xnr, wbp, vmw,
+    vec, trw, trv, skr, sdh, quc, pis, pcm, myv, mus, moh, mic,
+    mhn, ltg, lmo, lld, kxv, kpe, kgp, ken, kcg, kaj, jbo, gaa,
+    cic, cho, ceb, cch, cad, bss, blt, Tavt blo, bgn, bgc, rhg,
+    Rohg hnj, Hmnp Shaw, Dsrt bew, bal, arn, apc, ann, scn
+  * Drop Python < 3 support (using pyupgrade --py3-plus
+    langtable.py)
+  * Fix some ruff and pylint warnings
+
+-------------------------------------------------------------------

Old:
----
  langtable-0.0.66.tar.gz

New:
----
  langtable-0.0.67.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-langtable.spec ++++++
--- /var/tmp/diff_new_pack.nu3evU/_old  2024-07-08 19:07:26.184932316 +0200
+++ /var/tmp/diff_new_pack.nu3evU/_new  2024-07-08 19:07:26.188932462 +0200
@@ -27,7 +27,7 @@
 %define skip_python2 1
 %global literalpython python
 Name:           python-langtable%{psuffix}
-Version:        0.0.66
+Version:        0.0.67
 Release:        0
 Summary:        Database to guess defaults for locale settings
 # the translations in languages.xml and territories.xml are (mostly)

++++++ langtable-0.0.66.tar.gz -> langtable-0.0.67.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langtable-0.0.66/ChangeLog 
new/langtable-0.0.67/ChangeLog
--- old/langtable-0.0.66/ChangeLog      2024-05-07 18:25:07.000000000 +0200
+++ new/langtable-0.0.67/ChangeLog      2024-06-11 11:34:52.000000000 +0200
@@ -1,3 +1,10 @@
+2024-06-11  Mike FABIAN  <[email protected]>
+
+       * Add tool to check which languages, scripts, and territories available 
in CLDR are missing in langtable
+       * Add all missing scripts and languages: yrl, xnr, wbp, vmw, vec, trw, 
trv, skr, sdh, quc, pis, pcm, myv, mus, moh, mic, mhn, ltg, lmo, lld, kxv, kpe, 
kgp, ken, kcg, kaj, jbo, gaa, frr, csw, cic, cho, ceb, cch, cad, bss, blt, Tavt 
blo, bgn, bgc, rhg, Rohg hnj, Hmnp Shaw, Dsrt bew, bal, arn, apc, ann, scn
+       * Drop Python < 3 support (using pyupgrade --py3-plus langtable.py)
+       * Fix some ruff and pylint warnings
+
 2024-05-07  Mike FABIAN  <[email protected]>
 
        * Fix syntax error in a keyboard layout name for th
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langtable-0.0.66/Makefile 
new/langtable-0.0.67/Makefile
--- old/langtable-0.0.66/Makefile       2024-05-07 18:14:59.000000000 +0200
+++ new/langtable-0.0.67/Makefile       2024-06-11 12:08:02.000000000 +0200
@@ -52,6 +52,9 @@
 pip-install:
        (cd /tmp; python3 -m pip install --user --ignore-installed 
--no-cache-dir --no-deps langtable)
 
+.PHONY: pip-uninstall
+       pip uninstall langtable
+
 .PHONY: clean
 clean:
        git clean -dxf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langtable-0.0.66/PKG-INFO 
new/langtable-0.0.67/PKG-INFO
--- old/langtable-0.0.66/PKG-INFO       2024-05-07 18:51:53.230448200 +0200
+++ new/langtable-0.0.67/PKG-INFO       2024-06-11 12:08:13.412010700 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: langtable
-Version: 0.0.66
+Version: 0.0.67
 Summary: guess reasonable defaults for locale, keyboard, territory, ...
 Home-page: https://github.com/mike-fabian/langtable
 Author: Mike FABIAN
Binary files old/langtable-0.0.66/langtable/data/languages.xml.gz and 
new/langtable-0.0.67/langtable/data/languages.xml.gz differ
Binary files old/langtable-0.0.66/langtable/data/territories.xml.gz and 
new/langtable-0.0.67/langtable/data/territories.xml.gz differ
Binary files old/langtable-0.0.66/langtable/data/timezoneidparts.xml.gz and 
new/langtable-0.0.67/langtable/data/timezoneidparts.xml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langtable-0.0.66/langtable/langtable.py 
new/langtable-0.0.67/langtable/langtable.py
--- old/langtable-0.0.66/langtable/langtable.py 2024-02-13 17:18:42.000000000 
+0100
+++ new/langtable-0.0.67/langtable/langtable.py 2024-06-09 09:00:37.000000000 
+0200
@@ -1,5 +1,3 @@
-# vim:fileencoding=utf-8:sw=4:et -*- coding: utf-8 -*-
-
 # Copyright (c) 2013 Mike FABIAN <[email protected]>
 #
 # This program is free software: you can redistribute it and/or modify
@@ -15,96 +13,104 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>
 
-######################################################################
-# Public API:
-#
-#     parse_locale()
-#     list_locales()
-#     list_keyboards()
-#     list_common_languages()
-#     list_common_locales()
-#     list_common_keyboards()
-#     list_consolefonts()
-#     list_inputmethods()
-#     list_timezones()
-#     list_scripts()
-#     language_name()
-#     territory_name()
-#     timezone_name()
-#     languageId()
-#     territoryId()
-#     supports_ascii()
-#     list_all_languages()
-#     list_all_locales()
-#     list_all_keyboards()
-#     list_all_territories()
-#     list_all_timezones()
-#     list_all_scripts()
-#     list_all_input_methods()
-#     list_all_console_fonts()
-#
-# These are the functions which do not start with an “_” in their name.
-# All global functions and global variables whose name starts with an
-# “_” are internal and should not be used by a user of langtable.py.
-#
-# Many of the above public functions have named parameters like
-#
-#    languageId
-#    scriptId
-#    territoryId
-#
-# and
-#
-#    languageIdQuery
-#    scriptIdQuery
-#    territoryIdQuery
-#
-# languageId and languageIdQuery may contain a full locale name,
-# specifying the script and the territory as well.
-#
-# For example:
-#
-#     language_name(languageId="sr_Latn_RS")
-#
-# behaves the same as
-#
-#     language_name(languageId="sr", scriptId="Latn", territoryId="RS")
-#
-# If languageId contains a script or a territory, the values found there
-# are preferred over those given as extra parameters. For example:
-#
-#     language_name(languageId="sr_Latn_RS", scriptId="Cyrl", territoryId="ME")
-#
-# behaves the same as
-#
-#     language_name(languageId="sr", scriptId="Latn", territoryId="RS")
-#
-# scriptId="Cyrl" and territoryId="ME" are overridden by the values found
-# in languageId.
-#
-# It is also possible to put a full locale name in the spelling used by glibc
-# into languageId. For example:
-#
-#     language_name(languageId="sr_RS.utf8@latin")
-#
-# or
-#
-#     language_name(languageId="sr_RS.UTF-8@latin")
-#
-# also behave the same as:
-#
-#     language_name(languageId="sr_Latn_RS")
-#
-# which is the same as:
-#
-#     language_name(languageId="sr", scriptId="Latn", territoryId="RS")
-#
-# langtable always parses languageId, cuts out the encoding and translates
-# script names in glibc spelling like "latin" to the official
-# ISO 15924 script codes, see: https://en.wikipedia.org/wiki/ISO_15924
-#
-######################################################################
+'''
+Guessing reasonable defaults for locale, keyboard layout, territory, and 
language.
+
+langtable is used to guess reasonable defaults for locale, keyboard,
+territory, …, if part of that information is already known. For example,
+guess the territory and the keyboard layout if the language is known or guess
+the language and keyboard layout if the territory is already known.
+
+Public API:
 
+    parse_locale()
+    list_locales()
+    list_keyboards()
+    list_common_languages()
+    list_common_locales()
+    list_common_keyboards()
+    list_consolefonts()
+    list_inputmethods()
+    list_timezones()
+    list_scripts()
+    language_name()
+    territory_name()
+    timezone_name()
+    languageId()
+    territoryId()
+    supports_ascii()
+    list_all_languages()
+    list_all_locales()
+    list_all_keyboards()
+    list_all_territories()
+    list_all_timezones()
+    list_all_scripts()
+    list_all_input_methods()
+    list_all_console_fonts()
+
+These are the functions which do not start with an “_” in their name.
+All global functions and global variables whose name starts with an
+“_” are internal and should not be used by a user of langtable.py.
+
+Many of the above public functions have named parameters like
+
+   languageId
+   scriptId
+   territoryId
+
+and
+
+   languageIdQuery
+   scriptIdQuery
+   territoryIdQuery
+
+languageId and languageIdQuery may contain a full locale name,
+specifying the script and the territory as well.
+
+For example:
+
+    language_name(languageId="sr_Latn_RS")
+
+behaves the same as
+
+    language_name(languageId="sr", scriptId="Latn", territoryId="RS")
+
+If languageId contains a script or a territory, the values found there
+are preferred over those given as extra parameters. For example:
+
+    language_name(languageId="sr_Latn_RS", scriptId="Cyrl", territoryId="ME")
+
+behaves the same as
+
+    language_name(languageId="sr", scriptId="Latn", territoryId="RS")
+
+scriptId="Cyrl" and territoryId="ME" are overridden by the values found
+in languageId.
+
+It is also possible to put a full locale name in the spelling used by glibc
+into languageId. For example:
+
+    language_name(languageId="sr_RS.utf8@latin")
+
+or
+
+    language_name(languageId="sr_RS.UTF-8@latin")
+
+also behave the same as:
+
+    language_name(languageId="sr_Latn_RS")
+
+which is the same as:
+
+    language_name(languageId="sr", scriptId="Latn", territoryId="RS")
+
+langtable always parses languageId, cuts out the encoding and translates
+script names in glibc spelling like "latin" to the official
+ISO 15924 script codes, see: https://en.wikipedia.org/wiki/ISO_15924
+'''
+
+# pylint: disable=invalid-name
+# pylint: disable=redefined-outer-name
 from typing import List
 from typing import Dict
 import os
@@ -170,7 +176,8 @@
 _timezones_db = {}
 _timezoneIdParts_db = {}
 
-class territory_db_item:
+class territory_db_item: # pylint: disable=too-few-public-methods
+    '''Holds information for one territory'''
     def __init__(self, names = None, scripts=None, locales=None, 
languages=None, keyboards=None, inputmethods=None, consolefonts=None, 
timezones=None):
         self.names = names
         self.scripts = scripts
@@ -181,7 +188,8 @@
         self.consolefonts = consolefonts
         self.timezones = timezones
 
-class language_db_item:
+class language_db_item: # pylint: disable=too-few-public-methods
+    '''Holds information for one language'''
     def __init__(self, iso639_1=None, iso639_2_t=None, iso639_2_b=None, 
names=None, scripts=None, locales=None, territories=None, keyboards=None, 
inputmethods=None, consolefonts=None, timezones=None):
         self.iso639_1 = iso639_1
         self.iso639_2_t = iso639_2_t
@@ -195,7 +203,8 @@
         self.consolefonts = consolefonts
         self.timezones = timezones
 
-class keyboard_db_item:
+class keyboard_db_item: # pylint: disable=too-few-public-methods
+    '''Holds information for one keyboard layout'''
     def __init__(self, description=None, ascii=True, languages=None, 
territories = None, comment=None):
         self.description = description
         self.ascii  = ascii
@@ -203,17 +212,19 @@
         self.languages = languages
         self.territories = territories
 
-class timezone_db_item:
+class timezone_db_item: # pylint: disable=too-few-public-methods
+    '''Holds information for one timezone'''
     def __init__(self, names=None):
         self.names = names
 
-class timezoneIdPart_db_item:
+class timezoneIdPart_db_item: # pylint: disable=too-few-public-methods
+    '''Holds information for one timezone part'''
     def __init__(self, names=None):
         self.names = names
 
 # xml.sax.handler.ContentHandler is not inherited from the 'object' class,
 # 'super' keyword wouldn't work, we need to inherit it on our own
-class LangtableContentHandler(ContentHandler, object):
+class LangtableContentHandler(ContentHandler):
     """
     A base class inherited from the xml.sax.handler.ContentHandler class
     providing handling for SAX events produced when parsing the langtable data
@@ -222,6 +233,7 @@
     """
 
     def __init__(self):
+        super().__init__()
         # internal attribute used to set where the upcoming text data should be
         # stored
         self._save_to = None
@@ -246,7 +258,7 @@
     """Handler for SAX events produced when parsing the territories.xml 
file."""
 
     def __init__(self):
-        super(TerritoriesContentHandler, self).__init__()
+        super().__init__()
 
         # simple values
         self._territoryId = None
@@ -267,27 +279,27 @@
         self._timezones = None
 
     def startElement(self, name, attrs):
-        if name == u"territory":
-            self._names = dict()
-            self._scripts = dict()
-            self._locales = dict()
-            self._languages = dict()
-            self._keyboards = dict()
-            self._inputmethods = dict()
-            self._consolefonts = dict()
-            self._timezones = dict()
+        if name == "territory":
+            self._names = {}
+            self._scripts = {}
+            self._locales = {}
+            self._languages = {}
+            self._keyboards = {}
+            self._inputmethods = {}
+            self._consolefonts = {}
+            self._timezones = {}
 
         # non-dict values
-        elif name == u"territoryId":
+        elif name == "territoryId":
             self._save_to = "_territoryId"
 
         # dict items
-        elif name in (u"languageId", u"scriptId", u"localeId", u"keyboardId", 
u"inputmethodId",
-                      u"consolefontId", u"timezoneId"):
+        elif name in ("languageId", "scriptId", "localeId", "keyboardId", 
"inputmethodId",
+                      "consolefontId", "timezoneId"):
             self._save_to = "_item_id"
-        elif name == u"trName":
+        elif name == "trName":
             self._save_to = "_item_name"
-        elif name == u"rank":
+        elif name == "rank":
             self._save_to = "_item_rank"
 
     def endElement(self, name):
@@ -295,7 +307,7 @@
         # of an element no text should appear
         self._save_to = None
 
-        if name == u"territory":
+        if name == "territory":
             _territories_db[str(self._territoryId)] = territory_db_item(
                 names = self._names,
                 scripts = self._scripts,
@@ -318,28 +330,28 @@
             self._timezones = None
 
         # populating dictionaries
-        elif name == u"name":
+        elif name == "name":
             self._names[str(self._item_id)] = self._item_name
             self._clear_item()
-        elif name == u"script":
+        elif name == "script":
             self._scripts[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"locale":
+        elif name == "locale":
             self._locales[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"language":
+        elif name == "language":
             self._languages[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"keyboard":
+        elif name == "keyboard":
             self._keyboards[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"inputmethod":
+        elif name == "inputmethod":
             self._inputmethods[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"consolefont":
+        elif name == "consolefont":
             self._consolefonts[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"timezone":
+        elif name == "timezone":
             self._timezones[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
 
@@ -352,7 +364,7 @@
     """Handler for SAX events produced when parsing the keyboards.xml file."""
 
     def __init__(self):
-        super(KeyboardsContentHandler, self).__init__()
+        super().__init__()
 
         # simple values
         self._keyboardId = None
@@ -369,24 +381,24 @@
         self._territories = None
 
     def startElement(self, name, attrs):
-        if name == u"keyboard":
-            self._languages = dict()
-            self._territories = dict()
+        if name == "keyboard":
+            self._languages = {}
+            self._territories = {}
 
         # non-dict values
-        elif name == u"keyboardId":
+        elif name == "keyboardId":
             self._save_to = "_keyboardId"
-        elif name == u"description":
+        elif name == "description":
             self._save_to = "_description"
-        elif name == u"ascii":
+        elif name == "ascii":
             self._save_to = "_ascii"
-        elif name == u"comment":
+        elif name == "comment":
             self._save_to = "_comment"
 
         # dict items
-        elif name in (u"languageId", u"territoryId"):
+        elif name in ("languageId", "territoryId"):
             self._save_to = "_item_id"
-        elif name == u"rank":
+        elif name == "rank":
             self._save_to = "_item_rank"
 
     def endElement(self, name):
@@ -394,10 +406,10 @@
         # of an element no text should appear
         self._save_to = None
 
-        if name == u"keyboard":
+        if name == "keyboard":
             _keyboards_db[str(self._keyboardId)] = keyboard_db_item(
                 description = self._description,
-                ascii = self._ascii == u"True",
+                ascii = self._ascii == "True",
                 comment = self._comment,
                 languages = self._languages,
                 territories = self._territories)
@@ -411,10 +423,10 @@
             self._territories = None
 
         # populating dictionaries
-        elif name == u"language":
+        elif name == "language":
             self._languages[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"territory":
+        elif name == "territory":
             self._territories[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
 
@@ -426,7 +438,7 @@
     """Handler for SAX events produced when parsing the languages.xml file."""
 
     def __init__(self):
-        super(LanguagesContentHandler, self).__init__()
+        super().__init__()
         # simple values
         self._languageId = None
         self._iso639_1 = None
@@ -453,39 +465,39 @@
         self._timezones = None
 
     def startElement(self, name, attrs):
-        if name == u"language":
-            self._names = dict()
-            self._scripts = dict()
-            self._locales = dict()
-            self._territories = dict()
-            self._keyboards = dict()
-            self._inputmethods = dict()
-            self._consolefonts = dict()
-            self._timezones = dict()
+        if name == "language":
+            self._names = {}
+            self._scripts = {}
+            self._locales = {}
+            self._territories = {}
+            self._keyboards = {}
+            self._inputmethods = {}
+            self._consolefonts = {}
+            self._timezones = {}
 
         # non-dict values
-        elif name == u"languageId" and not self._in_names:
+        elif name == "languageId" and not self._in_names:
             # ID of the language
             self._save_to = "_languageId"
-        elif name == u"iso639-1":
+        elif name == "iso639-1":
             self._save_to = "_iso639_1"
-        elif name == u"iso639-2-t":
+        elif name == "iso639-2-t":
             self._save_to = "_iso639_2_t"
-        elif name == u"iso639-2-b":
+        elif name == "iso639-2-b":
             self._save_to = "_iso639_2_b"
-        elif name == u"names":
+        elif name == "names":
             self._in_names = True
 
         # dict items
-        elif name in (u"scriptId", u"localeId", u"territoryId", u"keyboardId", 
u"inputmethodId",
-                      u"consolefontId", u"timezoneId"):
+        elif name in ("scriptId", "localeId", "territoryId", "keyboardId", 
"inputmethodId",
+                      "consolefontId", "timezoneId"):
             self._save_to = "_item_id"
-        elif name == u"languageId" and self._in_names:
+        elif name == "languageId" and self._in_names:
             # ID of the translated name's language
             self._save_to = "_item_id"
-        elif name == u"trName":
+        elif name == "trName":
             self._save_to = "_item_name"
-        elif name == u"rank":
+        elif name == "rank":
             self._save_to = "_item_rank"
 
     def endElement(self, name):
@@ -493,7 +505,7 @@
         # of an element no text should appear
         self._save_to = None
 
-        if name == u"language":
+        if name == "language":
             _languages_db[str(self._languageId)] = language_db_item(
                 iso639_1 = self._iso639_1,
                 iso639_2_t = self._iso639_2_t,
@@ -522,32 +534,32 @@
             self._timezones = None
 
         # leaving the "names" element
-        elif name == u"names":
+        elif name == "names":
             self._in_names = False
 
         # populating dictionaries
-        elif name == u"name":
+        elif name == "name":
             self._names[str(self._item_id)] = self._item_name
             self._clear_item()
-        elif name == u"script":
+        elif name == "script":
             self._scripts[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"locale":
+        elif name == "locale":
             self._locales[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"territory":
+        elif name == "territory":
             self._territories[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"keyboard":
+        elif name == "keyboard":
             self._keyboards[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"inputmethod":
+        elif name == "inputmethod":
             self._inputmethods[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"consolefont":
+        elif name == "consolefont":
             self._consolefonts[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
-        elif name == u"timezone":
+        elif name == "timezone":
             self._timezones[str(self._item_id)] = int(self._item_rank)
             self._clear_item()
 
@@ -560,7 +572,7 @@
     """Handler for SAX events produced when parsing the timezones.xml file."""
 
     def __init__(self):
-        super(TimezonesContentHandler, self).__init__()
+        super().__init__()
         # simple values
         self._timezoneId = None
 
@@ -572,19 +584,19 @@
         self._names = None
 
     def startElement(self, name, attrs):
-        if name == u"timezone":
-            self._names = dict()
+        if name == "timezone":
+            self._names = {}
 
         # non-dict values
-        elif name == u"timezoneId":
+        elif name == "timezoneId":
             # ID of the timezone
             self._save_to = "_timezoneId"
 
         # dict items
-        elif name == u"languageId":
+        elif name == "languageId":
             # ID of the translated timezone's language
             self._save_to = "_item_id"
-        elif name == u"trName":
+        elif name == "trName":
             self._save_to = "_item_name"
 
     def endElement(self, name):
@@ -592,7 +604,7 @@
         # of an element no text should appear
         self._save_to = None
 
-        if name == u"timezone":
+        if name == "timezone":
             _timezones_db[str(self._timezoneId)] = timezone_db_item(
                 names = self._names)
 
@@ -601,7 +613,7 @@
             self._names = None
 
         # populating dictionaries
-        elif name == u"name":
+        elif name == "name":
             self._names[str(self._item_id)] = self._item_name
             self._clear_item()
 
@@ -613,7 +625,7 @@
     """Handler for SAX events produced when parsing the timezoneidparts.xml 
file."""
 
     def __init__(self):
-        super(TimezoneIdPartsContentHandler, self).__init__()
+        super().__init__()
         # simple values
         self._timezoneIdPartId = None
 
@@ -625,19 +637,19 @@
         self._names = None
 
     def startElement(self, name, attrs):
-        if name == u"timezoneIdPart":
-            self._names = dict()
+        if name == "timezoneIdPart":
+            self._names = {}
 
         # non-dict values
-        elif name == u"timezoneIdPartId":
+        elif name == "timezoneIdPartId":
             # partial timezone ID
             self._save_to = "_timezoneIdPartId"
 
         # dict items
-        elif name == u"languageId":
+        elif name == "languageId":
             # ID of the translated partial timezone ID's language
             self._save_to = "_item_id"
-        elif name == u"trName":
+        elif name == "trName":
             self._save_to = "_item_name"
 
     def endElement(self, name):
@@ -645,7 +657,7 @@
         # of an element no text should appear
         self._save_to = None
 
-        if name == u"timezoneIdPart":
+        if name == "timezoneIdPart":
             _timezoneIdParts_db[str(self._timezoneIdPartId)] = 
timezoneIdPart_db_item(
                 names = self._names)
 
@@ -654,7 +666,7 @@
             self._names = None
 
         # populating dictionaries
-        elif name == u"name":
+        elif name == "name":
             self._names[str(self._item_id)] = self._item_name
             self._clear_item()
 
@@ -745,7 +757,6 @@
         file.write('    </timezones>\n')
         file.write('  </territory>\n')
     file.write('</territories>\n')
-    return
 
 def _write_languages_file(file):
     '''
@@ -833,7 +844,6 @@
         file.write('    </timezones>\n')
         file.write('  </language>\n')
     file.write('</languages>\n')
-    return
 
 def _write_keyboards_file(file):
     '''
@@ -846,7 +856,7 @@
         file.write('    <keyboardId>'+keyboardId+'</keyboardId>\n')
         file.write('    
<description>'+_keyboards_db[keyboardId].description+'</description>\n')
         file.write('    
<ascii>'+str(_keyboards_db[keyboardId].ascii)+'</ascii>\n')
-        if _keyboards_db[keyboardId].comment != None:
+        if _keyboards_db[keyboardId].comment is not None:
             file.write('    
<comment>'+_keyboards_db[keyboardId].comment+'</comment>\n')
         languages = _keyboards_db[keyboardId].languages
         file.write('    <languages>\n')
@@ -868,7 +878,6 @@
         file.write('    </territories>\n')
         file.write('  </keyboard>\n')
     file.write('</keyboards>\n')
-    return
 
 def _write_timezones_file(file):
     '''
@@ -890,7 +899,6 @@
         file.write('    </names>\n')
         file.write('  </timezone>\n')
     file.write('</timezones>\n')
-    return
 
 def _write_timezoneIdParts_file(file):
     '''
@@ -912,7 +920,6 @@
         file.write('    </names>\n')
         file.write('  </timezoneIdPart>\n')
     file.write('</timezoneIdParts>\n')
-    return
 
 def _expat_parse(file, sax_handler):
     """
@@ -930,20 +937,20 @@
     '''
     Only for internal use
     '''
-    for dir in (
+    for directory in (
             os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data'),
             os.path.join(_DATADIR, 'data')):
-        path = os.path.join(dir, filename)
+        path = os.path.join(directory, filename)
         if os.path.isfile(path):
             with open(path, mode='rb') as file:
-                logging.info('reading file=%s' %file)
+                logging.info('reading file=%s', file)
                 _expat_parse(file, sax_handler)
                 _INFO['data_files_read'].append(path)
             return
-        path = os.path.join(dir, filename+'.gz')
+        path = os.path.join(directory, filename+'.gz')
         if os.path.isfile(path):
             with gzip.open(path, mode='rb') as file:
-                logging.info('reading file=%s' %file)
+                logging.info('reading file=%s', file)
                 _expat_parse(file, sax_handler)
                 _INFO['data_files_read'].append(path)
             return
@@ -953,31 +960,30 @@
     '''
     Only for internal use
     '''
-    with open(territoriesfilename, 'w') as territoriesfile:
-        logging.info("writing territories file=%s" %territoriesfile)
+    with open(territoriesfilename, 'w', encoding='UTF-8') as territoriesfile:
+        logging.info('writing territories file=%s', territoriesfile)
         _write_territories_file(territoriesfile)
-    with open(languagesfilename, 'w') as languagesfile:
-        logging.info("writing languages file=%s" %languagesfile)
+    with open(languagesfilename, 'w', encoding='UTF-8') as languagesfile:
+        logging.info('writing languages file=%s', languagesfile)
         _write_languages_file(languagesfile)
-    with open(keyboardsfilename, 'w') as keyboardsfile:
-        logging.info("writing keyboards file=%s" %keyboardsfile)
+    with open(keyboardsfilename, 'w', encoding='UTF-8') as keyboardsfile:
+        logging.info('writing keyboards file=%s', keyboardsfile)
         _write_keyboards_file(keyboardsfile)
-    with open(keyboardsfilename, 'w') as keyboardsfile:
-        logging.info("writing keyboards file=%s" %keyboardsfile)
+    with open(keyboardsfilename, 'w', encoding='UTF-8') as keyboardsfile:
+        logging.info('writing keyboards file=%s', keyboardsfile)
         _write_keyboards_file(keyboardsfile)
-    with open(timezonesfilename, 'w') as timezonesfile:
-        logging.info("writing timezones file=%s" %timezonesfile)
+    with open(timezonesfilename, 'w', encoding='UTF-8') as timezonesfile:
+        logging.info('writing timezones file=%s', timezonesfile)
         _write_timezones_file(timezonesfile)
-    with open(timezoneidpartsfilename, 'w') as timezoneidpartsfile:
-        logging.info("writing timezoneidparts file=%s" %timezoneidpartsfile)
+    with open(timezoneidpartsfilename, 'w', encoding='UTF-8') as 
timezoneidpartsfile:
+        logging.info('writing timezoneidparts file=%s', timezoneidpartsfile)
         _write_timezoneIdParts_file(timezoneidpartsfile)
-    return
 
-def _dictionary_to_ranked_list(dict, reverse=True):
+def _dictionary_to_ranked_list(dictionary, reverse=True):
     sorted_list = []
-    for item in sorted(dict, key=lambda x: (dict.get(x), x), reverse=reverse):
-        if dict[item] != 0:
-            sorted_list.append([item, dict[item]])
+    for item in sorted(dictionary, key=lambda x: (dictionary.get(x), x), 
reverse=reverse):
+        if dictionary[item] != 0:
+            sorted_list.append([item, dictionary[item]])
     return sorted_list
 
 def _ranked_list_to_list(ranked_list):
@@ -992,7 +998,7 @@
             break
     return ranked_list
 
-def _capitalize_name(text, languageId='', scriptId='', territoryId='', 
languageIdQuery='', scriptIdQuery='', territoryIdQuery=''):
+def _capitalize_name(text, languageId='', scriptId='', territoryId='', 
languageIdQuery='', scriptIdQuery='', territoryIdQuery=''): # pylint: 
disable=unused-argument
     '''
     Title cases the first letter of “text”
 
@@ -1023,7 +1029,7 @@
     if not languageIdQuery:
         languageIdQuery = 'en'
     for lang in ('ka', 'nr', 'ss', 'xh', 'yo', 'zu'):
-        if re.match(r'^%s' % lang, languageIdQuery):
+        if re.match(rf'^{lang}', languageIdQuery):
             return text
     return text[0].capitalize() + text[1:]
 
@@ -1185,7 +1191,7 @@
             if match.group('territory'):
                 territory = match.group('territory')
         else:
-            logging.info("localeId contains invalid locale id=%s" %localeId)
+            logging.info("localeId contains invalid locale id=%s", localeId)
     return Locale(language=language,
                   script=script,
                   territory=territory,
@@ -1295,8 +1301,7 @@
                         variant=locale.variant,
                         encoding=locale.encoding)
     if not locale.script and scriptId:
-        if scriptId in _glibc_script_ids:
-            scriptId = _glibc_script_ids[scriptId]
+        scriptId = _glibc_script_ids.get(scriptId, scriptId)
         locale = Locale(language=locale.language,
                         script=scriptId,
                         territory=locale.territory,
@@ -1326,7 +1331,7 @@
     return locale
 
 def territory_name(territoryId = None, languageIdQuery = None, scriptIdQuery = 
None, territoryIdQuery = None, fallback=True):
-    u'''Query translations of territory names
+    '''Query translations of territory names
 
     :param territoryId: identifier for the territory
     :type territoryId: string
@@ -1370,7 +1375,7 @@
         territoryIdQuery=territoryIdQuery)
 
 def _territory_name(territoryId = None, languageIdQuery = None, scriptIdQuery 
= None, territoryIdQuery = None, fallback=True):
-    u'''Internal function to query translations of territory names
+    '''Internal function to query translations of territory names
 
     :param territoryId: identifier for the territory
     :type territoryId: string
@@ -1421,7 +1426,7 @@
     return ''
 
 def language_name(languageId = None, scriptId = None, territoryId = None, 
languageIdQuery = None, scriptIdQuery = None, territoryIdQuery = None, 
fallback=True):
-    u'''Query translations of language names
+    '''Query translations of language names
 
     :param languageId: identifier for the language
     :type languageId: string
@@ -1515,7 +1520,7 @@
         territoryIdQuery=territoryIdQuery)
 
 def _language_name(languageId = None, scriptId = None, territoryId = None, 
languageIdQuery = None, scriptIdQuery = None, territoryIdQuery = None, 
fallback=True):
-    u'''Internal function to query translations of language names
+    '''Internal function to query translations of language names
 
     :param languageId: identifier for the language
     :type languageId: string
@@ -1627,7 +1632,7 @@
                 icuLocaleIdQuery = languageIdQuery
                 if icuLocaleIdQuery in _languages_db[icuLocaleId].names:
                     return _languages_db[icuLocaleId].names[icuLocaleIdQuery]
-        if not locale.variant in ('VALENCIA',):
+        if locale.variant not in ('VALENCIA',):
             # Don’t do this if locale variant is VALENCIA
             # because then this will run into endless recursion:
             lname = language_name(languageId=languageId,
@@ -1693,7 +1698,7 @@
             name = timezoneId_part.replace('_', ' ')
             part_names.append(name)
     if len(part_names) == len(timezoneId_parts):
-        return u'/'.join(part_names)
+        return '/'.join(part_names)
     return ''
 
 def _timezone_name(timezoneId = None, icuLocaleIdQuery = None):
@@ -1712,7 +1717,7 @@
     return ''
 
 def timezone_name(timezoneId = None, languageIdQuery = None, scriptIdQuery = 
None, territoryIdQuery = None):
-    u'''Query translations of timezone IDs
+    '''Query translations of timezone IDs
 
     :param timezoneId: identifier for the time zone
     :type timezoneId: string
@@ -1767,7 +1772,7 @@
             return name
     return timezoneId
 
-def territoryId(territoryName = u''):
+def territoryId(territoryName = ''):
     '''Query the territoryId from a translated name of a territory.
 
     :param territoryName: the translated name of a language
@@ -1800,15 +1805,15 @@
     '''
     if not territoryName:
         return ''
-    if type(territoryName) != type(u''):
+    if not isinstance(territoryName, str):
         territoryName = territoryName.decode('UTF-8')
-    for territoryId in _territories_db:
-        for icuLocaleId in _territories_db[territoryId].names:
-            if territoryName == 
_territories_db[territoryId].names[icuLocaleId]:
+    for territoryId, territory_item in _territories_db.items():
+        for name in territory_item.names.values():
+            if territoryName == name:
                 return territoryId
     return ''
 
-def languageId(languageName = u''):
+def languageId(languageName = ''):
     '''Query the languageId from a translated name of a language.
 
     :param languageName: the translated name of a language
@@ -1835,11 +1840,11 @@
     '''
     if not languageName:
         return ''
-    if type(languageName) != type(u''):
+    if not isinstance(languageName, str):
         languageName = languageName.decode('UTF-8')
-    for languageId in _languages_db:
-        for icuLocaleId in _languages_db[languageId].names:
-            if languageName.lower() == 
_languages_db[languageId].names[icuLocaleId].lower():
+    for languageId, language_item in _languages_db.items():
+        for name in language_item.names.values():
+            if languageName.lower() == name.lower():
                 return languageId
     language_territory_pattern = re.compile(
         r'^(?P<language_name>[^()]+)[\s]+[(](?P<territory_name>[^()]+)[)]',
@@ -1848,12 +1853,12 @@
     if match:
         language_name = match.group('language_name')
         territory_name = match.group('territory_name')
-        for languageId in _languages_db:
-            for icuLocaleId in _languages_db[languageId].names:
-                if language_name.lower() == 
_languages_db[languageId].names[icuLocaleId].lower():
-                    for territoryId in _territories_db:
-                        for icuLocaleId_territory in 
_territories_db[territoryId].names:
-                            if territory_name.lower() == 
_territories_db[territoryId].names[icuLocaleId_territory].lower():
+        for languageId, language_item in _languages_db.items():
+            for language_item_name in language_item.names.values():
+                if language_name.lower() == language_item_name.lower():
+                    for territoryId, territory_item in _territories_db.items():
+                        for territory_item_name in 
territory_item.names.values():
+                            if territory_name.lower() == 
territory_item_name.lower():
                                 return languageId+'_'+territoryId
 
     return ''
@@ -1940,8 +1945,7 @@
         ranked_list = _make_ranked_list_concise(ranked_list)
     if show_weights:
         return ranked_list
-    else:
-        return _ranked_list_to_list(ranked_list)
+    return _ranked_list_to_list(ranked_list)
 
 def list_common_languages():
     '''List common languages
@@ -1959,7 +1963,7 @@
 
     '''
 
-    common_locales = list()
+    common_locales = []
     common_locales.append("ar_EG.UTF-8")
     common_locales.append("en_US.UTF-8")
     common_locales.append("fr_FR.UTF-8")
@@ -2067,8 +2071,7 @@
         ranked_list = _make_ranked_list_concise(ranked_list)
     if show_weights:
         return ranked_list
-    else:
-        return _ranked_list_to_list(ranked_list)
+    return _ranked_list_to_list(ranked_list)
 
 def list_inputmethods(concise=True, show_weights=False, languageId = None, 
scriptId = None, territoryId = None):
     '''List suitable input methods
@@ -2143,8 +2146,7 @@
         ranked_list = _make_ranked_list_concise(ranked_list)
     if show_weights:
         return ranked_list
-    else:
-        return _ranked_list_to_list(ranked_list)
+    return _ranked_list_to_list(ranked_list)
 
 def list_keyboards(concise=True, show_weights=False, languageId = None, 
scriptId = None, territoryId = None):
     '''List likely X11 keyboard layouts
@@ -2220,10 +2222,10 @@
         ranked_list = _make_ranked_list_concise(ranked_list)
     if show_weights:
         return ranked_list
-    else:
-        return _ranked_list_to_list(ranked_list)
+    return _ranked_list_to_list(ranked_list)
 
 def list_common_keyboards(languageId = None, scriptId = None, territoryId = 
None):
+    # pylint: disable=line-too-long
     '''Returns highest ranked keyboard layout(s)
 2
     :param languageId: identifier for the language
@@ -2238,7 +2240,7 @@
     **Examples:**
 
     >>> list_common_keyboards()
-    ['af(ps)', 'al', 'am', 'ara', 'az', 'ba', 'be(oss)', 'bg', 'br', 'bt', 
'by', 'ca(eng)', 'ca(ike)', 'ch', 'cn', 'cn(ug)', 'cz', 'de(nodeadkeys)', 'dk', 
'ee', 'es', 'es(ast)', 'es(cat)', 'et', 'fi', 'fo', 'fr(bre)', 'fr(oss)', 'gb', 
'ge', 'gr', 'hr', 'hu', 'ie(CloGaelach)', 'il', 'in(eng)', 'ir', 'is', 'it', 
'jp', 'ke', 'kg', 'kh', 'kr', 'kz', 'la', 'latam', 'lt', 'lv', 'ma(tifinagh)', 
'mk', 'mm', 'mn', 'mt', 'mv', 'ng(hausa)', 'ng(igbo)', 'ng(yoruba)', 'no', 
'np', 'ph', 'pk', 'pl', 'ro', 'rs', 'rs(latin)', 'ru', 'ru(bak)', 'ru(chm)', 
'ru(cv)', 'ru(kom)', 'ru(os_winkeys)', 'ru(sah)', 'ru(tt)', 'ru(udm)', 
'ru(xal)', 'se', 'si', 'sk', 'sn', 'syc', 'th', 'tj', 'tm', 'tr', 'tr(crh)', 
'tr(ku)', 'tw', 'ua', 'us', 'us(altgr-intl)', 'us(euro)', 'us(intl)', 'uz', 
'vn', 'za']
+    ['af(ps)', 'al', 'am', 'ara', 'au', 'az', 'ba', 'be(oss)', 'bg', 'br', 
'bt', 'by', 'ca(eng)', 'ca(ike)', 'ch', 'cn', 'cn(ug)', 'cz', 'de(nodeadkeys)', 
'dk', 'ee', 'es', 'es(ast)', 'es(cat)', 'et', 'fi', 'fo', 'fr(bre)', 'fr(oss)', 
'gb', 'ge', 'gr', 'hr', 'hu', 'ie(CloGaelach)', 'il', 'in(eng)', 'ir', 'is', 
'it', 'jp', 'ke', 'kg', 'kh', 'kr', 'kz', 'la', 'latam', 'lt', 'lv', 
'ma(tifinagh)', 'mk', 'mm', 'mn', 'mt', 'mv', 'ng', 'ng(hausa)', 'ng(igbo)', 
'ng(yoruba)', 'no', 'np', 'ph', 'pk', 'pl', 'pt', 'ro', 'rs', 'rs(latin)', 
'ru', 'ru(bak)', 'ru(chm)', 'ru(cv)', 'ru(kom)', 'ru(os_winkeys)', 'ru(sah)', 
'ru(tt)', 'ru(udm)', 'ru(xal)', 'se', 'si', 'sk', 'sn', 'syc', 'th', 'tj', 
'tm', 'tr', 'tr(crh)', 'tr(ku)', 'tw', 'ua', 'us', 'us(altgr-intl)', 
'us(euro)', 'us(intl)', 'uz', 'vn', 'za']
     >>> list_common_keyboards(languageId='fr')
     ['fr(oss)']
     >>> list_common_keyboards(territoryId='CA')
@@ -2256,7 +2258,8 @@
     >>> list_common_keyboards(languageId='zh', scriptId='Hans', 
territoryId='TW')
     ['tw']
     '''
-    high_ranked_keyboards = list()
+    # pylint: enable=line-too-long
+    high_ranked_keyboards = []
     if not languageId and not scriptId and not territoryId:
         for _, language in _languages_db.items():
             keyboard_layouts = language.keyboards
@@ -2266,16 +2269,16 @@
                 high_ranked_keyboards.extend(selected_layouts)
         high_ranked_keyboards = list(set(high_ranked_keyboards))
 
-    kwargs = dict()
+    kwargs = {}
     locale = _parse_and_split_languageId(
         languageId=languageId, scriptId=scriptId, territoryId=territoryId
     )
     if locale.language:
-        kwargs.update(dict(languageId=locale.language))
+        kwargs.update({'languageId': locale.language})
     if locale.script:
-        kwargs.update(dict(scriptId=locale.script))
+        kwargs.update({'scriptId': locale.script})
     if locale.territory:
-        kwargs.update(dict(territoryId=locale.territory))
+        kwargs.update({'territoryId': locale.territory})
     common_layouts = list_keyboards(**kwargs)
     if common_layouts:
         # Picking up first layout from the list
@@ -2330,7 +2333,7 @@
     >>> list_common_locales(languageId='zh', territoryId='TW')
     ['zh_TW.UTF-8']
     '''
-    high_ranked_locales = list()
+    high_ranked_locales = []
     if not languageId and not scriptId and not territoryId:
         for language in list_common_languages():
             locales = _languages_db[language].locales
@@ -2342,16 +2345,16 @@
                 high_ranked_locales.extend(selected_locales)
         return high_ranked_locales
 
-    kwargs = dict()
+    kwargs = {}
     locale = _parse_and_split_languageId(
         languageId=languageId, scriptId=scriptId, territoryId=territoryId
     )
     if locale.language:
-        kwargs.update(dict(languageId=locale.language))
+        kwargs.update({'languageId': locale.language})
     if locale.script:
-        kwargs.update(dict(scriptId=locale.script))
+        kwargs.update({'scriptId': locale.script})
     if locale.territory:
-        kwargs.update(dict(territoryId=locale.territory))
+        kwargs.update({'territoryId': locale.territory})
     common_locales = list_locales(**kwargs)
     if common_locales:
         # Picking up first locale from the list
@@ -2359,7 +2362,7 @@
     return high_ranked_locales
 
 def list_consolefonts(concise=True, show_weights=False, languageId = None, 
scriptId = None, territoryId = None):
-    u'''List likely Linux Console fonts
+    '''List likely Linux Console fonts
 
     :param concise: if True, return only to highly ranked results
     :type concise: boolean
@@ -2454,8 +2457,7 @@
         ranked_list = _make_ranked_list_concise(ranked_list)
     if show_weights:
         return ranked_list
-    else:
-        return _ranked_list_to_list(ranked_list)
+    return _ranked_list_to_list(ranked_list)
 
 def list_timezones(concise=True, show_weights=False, languageId = None, 
scriptId = None, territoryId = None):
     '''List likely timezones
@@ -2535,8 +2537,7 @@
         ranked_list = _make_ranked_list_concise(ranked_list)
     if show_weights:
         return ranked_list
-    else:
-        return _ranked_list_to_list(ranked_list)
+    return _ranked_list_to_list(ranked_list)
 
 def list_all_languages() -> List[str]:
     '''
@@ -2640,22 +2641,23 @@
     Return version of langtable
     '''
     # pkg_resources is part of setuptools
-    import pkg_resources  # type: ignore
+    import pkg_resources  # type: ignore pylint: 
disable=import-outside-toplevel
     return pkg_resources.require("langtable")[0].version
 
 def info():
     '''
     Print some info about langtable
     '''
-    import pkg_resources  # part of setuptools
+    # pkg_resources is part of setuptools
+    import pkg_resources  # type: ignore pylint: 
disable=import-outside-toplevel
     project_name = pkg_resources.require("langtable")[0].project_name
     version = pkg_resources.require("langtable")[0].version
     module_path = pkg_resources.require("langtable")[0].module_path
-    print('Project name: = %s' %project_name)
-    print('Version: = %s' %version)
-    print('Module path: = %s' %module_path)
-    print('Loaded from: %s' %os.path.realpath(__file__))
-    print('Data files read: %s' %_INFO['data_files_read'])
+    print(f'Project name: = {project_name}')
+    print(f'Version: = {version}')
+    print(f'Module path: = {module_path}')
+    print(f'Loaded from: {os.path.realpath(__file__)}')
+    print(f'Data files read: {_INFO["data_files_read"]}')
 
 def _test_cldr_locale_pattern(localeId):
     '''
@@ -2664,8 +2666,7 @@
     match = _cldr_locale_pattern.match(localeId)
     if match:
         return [('language', match.group('language')), ('script', 
match.group('script')), ('territory', match.group('territory'))]
-    else:
-        return  []
+    return []
 
 def _test_language_territory(show_weights=False, languageId=None, 
scriptId=None, territoryId=None):
     '''
@@ -2689,9 +2690,8 @@
           +" +: "
           
+repr(list_keyboards(show_weights=show_weights,languageId=languageId,scriptId=scriptId,territoryId=territoryId))
           )
-    return
 
-def _init(debug=False, logfilename='/dev/null'):
+def _init(debug=False, logfilename='/dev/null') -> None:
 
     log_level = logging.INFO
     if debug:
@@ -2707,12 +2707,13 @@
     _read_file('timezones.xml', TimezonesContentHandler())
     _read_file('timezoneidparts.xml', TimezoneIdPartsContentHandler())
 
-class __ModuleInitializer:
-    def __init__(self):
+# pylint: enable=invalid-name
+
+class __ModuleInitializer: # pylint: 
disable=too-few-public-methods,invalid-name
+    def __init__(self) -> None:
         _init()
-        return
 
-    def __del__(self):
+    def __del__(self) -> None:
         return
 
 __module_init = __ModuleInitializer()
@@ -2725,5 +2726,5 @@
     print(f'{ATTEMPTED} tests run. {ATTEMPTED - FAILED} passed and {FAILED} 
failed.')
     if FAILED:
         sys.exit(FAILED)
-    print(f'All tests passed.')
+    print('All tests passed.')
     sys.exit(0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langtable-0.0.66/langtable.egg-info/PKG-INFO 
new/langtable-0.0.67/langtable.egg-info/PKG-INFO
--- old/langtable-0.0.66/langtable.egg-info/PKG-INFO    2024-05-07 
18:51:53.000000000 +0200
+++ new/langtable-0.0.67/langtable.egg-info/PKG-INFO    2024-06-11 
12:08:13.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: langtable
-Version: 0.0.66
+Version: 0.0.67
 Summary: guess reasonable defaults for locale, keyboard, territory, ...
 Home-page: https://github.com/mike-fabian/langtable
 Author: Mike FABIAN
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langtable-0.0.66/langtable.egg-info/SOURCES.txt 
new/langtable-0.0.67/langtable.egg-info/SOURCES.txt
--- old/langtable-0.0.66/langtable.egg-info/SOURCES.txt 2024-05-07 
18:51:53.000000000 +0200
+++ new/langtable-0.0.67/langtable.egg-info/SOURCES.txt 2024-06-11 
12:08:13.000000000 +0200
@@ -27,4 +27,5 @@
 langtable/schemas/timezoneidparts.rng
 langtable/schemas/timezones.rng
 tools/compare_with_glib_source.py
+tools/list-missing-from-cldr
 tools/list-missing-regions-and-languages.sh
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langtable-0.0.66/setup.py 
new/langtable-0.0.67/setup.py
--- old/langtable-0.0.66/setup.py       2024-05-07 18:25:07.000000000 +0200
+++ new/langtable-0.0.67/setup.py       2024-06-11 11:35:17.000000000 +0200
@@ -8,7 +8,7 @@
     # within the egg directory easily:
     zip_safe=False,
     name='langtable',
-    version='0.0.66',
+    version='0.0.67',
     packages=setuptools.find_packages(),
     description='guess reasonable defaults for locale, keyboard, territory, 
...',
     long_description=codecs.open('README.md', encoding='UTF-8').read(),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langtable-0.0.66/test_cases.py 
new/langtable-0.0.67/test_cases.py
--- old/langtable-0.0.66/test_cases.py  2024-05-07 18:25:07.000000000 +0200
+++ new/langtable-0.0.67/test_cases.py  2024-06-06 18:02:08.000000000 +0200
@@ -2134,7 +2134,7 @@
     >>> print(langtable.timezone_name(timezoneId='Pacific/Pago_Pago', 
languageIdQuery='ast'))  # doctest: +NORMALIZE_WHITESPACE
         Océanu Pacíficu/Pago Pago
     >>> print(list_common_keyboards())  # doctest: +NORMALIZE_WHITESPACE
-        ['af(ps)', 'al', 'am', 'ara', 'az', 'ba', 'be(oss)', 'bg', 'br', 'bt', 
'by', 'ca(eng)', 'ca(ike)', 'ch', 'cn', 'cn(ug)', 'cz', 'de(nodeadkeys)', 'dk', 
'ee', 'es', 'es(ast)', 'es(cat)', 'et', 'fi', 'fo', 'fr(bre)', 'fr(oss)', 'gb', 
'ge', 'gr', 'hr', 'hu', 'ie(CloGaelach)', 'il', 'in(eng)', 'ir', 'is', 'it', 
'jp', 'ke', 'kg', 'kh', 'kr', 'kz', 'la', 'latam', 'lt', 'lv', 'ma(tifinagh)', 
'mk', 'mm', 'mn', 'mt', 'mv', 'ng(hausa)', 'ng(igbo)', 'ng(yoruba)', 'no', 
'np', 'ph', 'pk', 'pl', 'ro', 'rs', 'rs(latin)', 'ru', 'ru(bak)', 'ru(chm)', 
'ru(cv)', 'ru(kom)', 'ru(os_winkeys)', 'ru(sah)', 'ru(tt)', 'ru(udm)', 
'ru(xal)', 'se', 'si', 'sk', 'sn', 'syc', 'th', 'tj', 'tm', 'tr', 'tr(crh)', 
'tr(ku)', 'tw', 'ua', 'us', 'us(altgr-intl)', 'us(euro)', 'us(intl)', 'uz', 
'vn', 'za']
+        ['af(ps)', 'al', 'am', 'ara', 'au', 'az', 'ba', 'be(oss)', 'bg', 'br', 
'bt', 'by', 'ca(eng)', 'ca(ike)', 'ch', 'cn', 'cn(ug)', 'cz', 'de(nodeadkeys)', 
'dk', 'ee', 'es', 'es(ast)', 'es(cat)', 'et', 'fi', 'fo', 'fr(bre)', 'fr(oss)', 
'gb', 'ge', 'gr', 'hr', 'hu', 'ie(CloGaelach)', 'il', 'in(eng)', 'ir', 'is', 
'it', 'jp', 'ke', 'kg', 'kh', 'kr', 'kz', 'la', 'latam', 'lt', 'lv', 
'ma(tifinagh)', 'mk', 'mm', 'mn', 'mt', 'mv', 'ng', 'ng(hausa)', 'ng(igbo)', 
'ng(yoruba)', 'no', 'np', 'ph', 'pk', 'pl', 'pt', 'ro', 'rs', 'rs(latin)', 
'ru', 'ru(bak)', 'ru(chm)', 'ru(cv)', 'ru(kom)', 'ru(os_winkeys)', 'ru(sah)', 
'ru(tt)', 'ru(udm)', 'ru(xal)', 'se', 'si', 'sk', 'sn', 'syc', 'th', 'tj', 
'tm', 'tr', 'tr(crh)', 'tr(ku)', 'tw', 'ua', 'us', 'us(altgr-intl)', 
'us(euro)', 'us(intl)', 'uz', 'vn', 'za']
     >>> print(list_common_keyboards(languageId='fr'))  # doctest: 
+NORMALIZE_WHITESPACE
         ['fr(oss)']
     >>> print(list_common_keyboards(territoryId='CA'))   # doctest: 
+NORMALIZE_WHITESPACE
@@ -2155,9 +2155,9 @@
         ['ar', 'en', 'fr', 'de', 'ja', 'zh', 'ru', 'es']
 
     >>> print(list_all_languages())    # doctest: +NORMALIZE_WHITESPACE
-    ['aa', 'ab', 'af', 'agq', 'agr', 'ak', 'am', 'an', 'anp', 'ar', 'as', 
'asa', 'ast', 'av', 'ay', 'ayc', 'ayr', 'az', 'ba', 'bas', 'be', 'bem', 'ber', 
'bez', 'bg', 'bhb', 'bho', 'bi', 'bih', 'bin', 'bm', 'bn', 'bo', 'br', 'brx', 
'bs', 'bua', 'byn', 'ca', 'ca_ES_VALENCIA', 'ccp', 'ce', 'cgg', 'ch', 'chm', 
'chr', 'ckb', 'cmn', 'co', 'cop', 'crh', 'cs', 'csb', 'cu', 'cv', 'cy', 'da', 
'dav', 'de', 'dje', 'doi', 'dsb', 'dua', 'dv', 'dyo', 'dz', 'ebu', 'ee', 'el', 
'en', 'eo', 'es', 'et', 'eu', 'ewo', 'fa', 'fat', 'ff', 'fi', 'fil', 'fj', 
'fo', 'fr', 'fur', 'fy', 'ga', 'gbm', 'gd', 'gez', 'gl', 'glk', 'gn', 'grc', 
'gsw', 'gu', 'guz', 'gv', 'ha', 'hak', 'haw', 'he', 'hi', 'hif', 'hil', 'hne', 
'ho', 'hr', 'hsb', 'ht', 'hu', 'hy', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik', 
'ilo', 'io', 'is', 'it', 'iu', 'iw', 'ja', 'jgo', 'jmc', 'jv', 'ka', 'kaa', 
'kab', 'kam', 'kde', 'kea', 'kg', 'khb', 'khq', 'ki', 'kj', 'kk', 'kkj', 'kl', 
'kln', 'km', 'kn', 'ko', 'kok', 'kr', 'ks', 'ks_Arab', 'ks_Deva', '
 ksb', 'ksf', 'ksh', 'ku', 'kum', 'kv', 'kw', 'kwm', 'ky', 'la', 'lag', 'lah', 
'lb', 'lez', 'lg', 'li', 'lij', 'lkt', 'ln', 'lo', 'lrc', 'lt', 'lu', 'luo', 
'luy', 'lv', 'lzh', 'mag', 'mai', 'mas', 'mdf', 'mer', 'mfe', 'mg', 'mgh', 
'mgo', 'mh', 'mhr', 'mi', 'miq', 'mjw', 'mk', 'ml', 'mn', 'mni', 'mnw', 'mo', 
'mos', 'mr', 'ms', 'mt', 'mua', 'my', 'mzn', 'na', 'nan', 'naq', 'nb', 'nd', 
'nds', 'ne', 'new', 'ng', 'nhn', 'niu', 'nl', 'nmg', 'nn', 'nnh', 'no', 'nqo', 
'nr', 'nso', 'nus', 'nv', 'ny', 'nyn', 'oc', 'om', 'or', 'os', 'osa', 'ota', 
'pa', 'pap', 'pl', 'prg', 'ps', 'pt', 'qu', 'quh', 'quz', 'raj', 'rif', 'rm', 
'rn', 'ro', 'rof', 'ru', 'rw', 'rwk', 'sa', 'sah', 'saq', 'sat', 'sbp', 'sc', 
'sco', 'sd', 'sd_Arab', 'sd_Deva', 'se', 'seh', 'sel', 'ses', 'sg', 'sgs', 
'sh', 'shi', 'shn', 'shs', 'si', 'sid', 'sk', 'sl', 'sm', 'sma', 'smj', 'smn', 
'sms', 'sn', 'so', 'sq', 'sr', 'sr_Cyrl', 'sr_Latn', 'ss', 'ssy', 'st', 'su', 
'sv', 'sw', 'syc', 'syr', 'szl', 'ta', 'tcy', 'te', 'teo', 'tet', 't
 g', 'th', 'the', 'ti', 'tig', 'tk', 'tl', 'tn', 'to', 'tok', 'tpi', 'tr', 
'ts', 'tt', 'tt_Cyrl', 'tt_Latn', 'tw', 'twq', 'txg', 'ty', 'tyv', 'tzm', 
'udm', 'ug', 'uk', 'unm', 'ur', 'uz', 'vai', 've', 'vi', 'vo', 'vot', 'vun', 
'wa', 'wae', 'wal', 'wen', 'wo', 'wuu', 'xal', 'xh', 'xog', 'xzh', 'yap', 
'yav', 'yi', 'yo', 'yue', 'yuw', 'za', 'zgh', 'zh', 'zh_Hans', 'zh_Hans_CN', 
'zh_Hans_SG', 'zh_Hant', 'zh_Hant_HK', 'zh_Hant_MO', 'zh_Hant_TW', 'zu']
+    ['aa', 'ab', 'af', 'agq', 'agr', 'ak', 'am', 'an', 'ann', 'anp', 'apc', 
'ar', 'arn', 'as', 'asa', 'ast', 'av', 'ay', 'ayc', 'ayr', 'az', 'ba', 'bal', 
'bas', 'be', 'bem', 'ber', 'bew', 'bez', 'bg', 'bgc', 'bgn', 'bhb', 'bho', 
'bi', 'bih', 'bin', 'blo', 'blt', 'bm', 'bn', 'bo', 'br', 'brx', 'bs', 'bss', 
'bua', 'byn', 'ca', 'ca_ES_VALENCIA', 'cad', 'cch', 'ccp', 'ce', 'ceb', 'cgg', 
'ch', 'chm', 'cho', 'chr', 'cic', 'ckb', 'cmn', 'co', 'cop', 'crh', 'cs', 
'csb', 'csw', 'cu', 'cv', 'cy', 'da', 'dav', 'de', 'dje', 'doi', 'dsb', 'dua', 
'dv', 'dyo', 'dz', 'ebu', 'ee', 'el', 'en', 'eo', 'es', 'et', 'eu', 'ewo', 
'fa', 'fat', 'ff', 'fi', 'fil', 'fj', 'fo', 'fr', 'frr', 'fur', 'fy', 'ga', 
'gaa', 'gbm', 'gd', 'gez', 'gl', 'glk', 'gn', 'grc', 'gsw', 'gu', 'guz', 'gv', 
'ha', 'hak', 'haw', 'he', 'hi', 'hif', 'hil', 'hne', 'hnj', 'ho', 'hr', 'hsb', 
'ht', 'hu', 'hy', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'ilo', 'io', 'is', 
'it', 'iu', 'iw', 'ja', 'jbo', 'jgo', 'jmc', 'jv', 'ka', 'kaa', 'kab',
  'kaj', 'kam', 'kcg', 'kde', 'kea', 'ken', 'kg', 'kgp', 'khb', 'khq', 'ki', 
'kj', 'kk', 'kkj', 'kl', 'kln', 'km', 'kn', 'ko', 'kok', 'kpe', 'kr', 'ks', 
'ks_Arab', 'ks_Deva', 'ksb', 'ksf', 'ksh', 'ku', 'kum', 'kv', 'kw', 'kwm', 
'kxv', 'kxv_Deva', 'kxv_Orya', 'kxv_Telu', 'ky', 'la', 'lag', 'lah', 'lb', 
'lez', 'lg', 'li', 'lij', 'lkt', 'lld', 'lmo', 'ln', 'lo', 'lrc', 'lt', 'ltg', 
'lu', 'luo', 'luy', 'lv', 'lzh', 'mag', 'mai', 'mas', 'mdf', 'mer', 'mfe', 
'mg', 'mgh', 'mgo', 'mh', 'mhn', 'mhr', 'mi', 'mic', 'miq', 'mjw', 'mk', 'ml', 
'mn', 'mni', 'mnw', 'mo', 'moh', 'mos', 'mr', 'ms', 'mt', 'mua', 'mus', 'my', 
'myv', 'mzn', 'na', 'nan', 'naq', 'nb', 'nd', 'nds', 'ne', 'new', 'ng', 'nhn', 
'niu', 'nl', 'nmg', 'nn', 'nnh', 'no', 'nqo', 'nr', 'nso', 'nus', 'nv', 'ny', 
'nyn', 'oc', 'om', 'or', 'os', 'osa', 'ota', 'pa', 'pap', 'pcm', 'pis', 'pl', 
'prg', 'ps', 'pt', 'qu', 'quc', 'quh', 'quz', 'raj', 'rhg', 'rif', 'rm', 'rn', 
'ro', 'rof', 'ru', 'rw', 'rwk', 'sa', 'sah', 'saq', 'sat', 'sbp', 'sc'
 , 'scn', 'sco', 'sd', 'sd_Arab', 'sd_Deva', 'sdh', 'se', 'seh', 'sel', 'ses', 
'sg', 'sgs', 'sh', 'shi', 'shn', 'shs', 'si', 'sid', 'sk', 'skr', 'sl', 'sm', 
'sma', 'smj', 'smn', 'sms', 'sn', 'so', 'sq', 'sr', 'sr_Cyrl', 'sr_Latn', 'ss', 
'ssy', 'st', 'su', 'sv', 'sw', 'syc', 'syr', 'szl', 'ta', 'tcy', 'te', 'teo', 
'tet', 'tg', 'th', 'the', 'ti', 'tig', 'tk', 'tl', 'tn', 'to', 'tok', 'tpi', 
'tr', 'trv', 'trw', 'ts', 'tt', 'tt_Cyrl', 'tt_Latn', 'tw', 'twq', 'txg', 'ty', 
'tyv', 'tzm', 'udm', 'ug', 'uk', 'unm', 'ur', 'uz', 'vai', 've', 'vec', 'vi', 
'vmw', 'vo', 'vot', 'vun', 'wa', 'wae', 'wal', 'wbp', 'wen', 'wo', 'wuu', 
'xal', 'xh', 'xnr', 'xnr_Deva', 'xnr_Takr', 'xog', 'xzh', 'yap', 'yav', 'yi', 
'yo', 'yrl', 'yue', 'yuw', 'za', 'zgh', 'zh', 'zh_Hans', 'zh_Hans_CN', 
'zh_Hans_SG', 'zh_Hant', 'zh_Hant_HK', 'zh_Hant_MO', 'zh_Hant_TW', 'zu']
     >>> print(list_all_locales())    # doctest: +NORMALIZE_WHITESPACE
-    ['aa_DJ.UTF-8', 'aa_ER.UTF-8', 'aa_ET.UTF-8', 'ab_GE.UTF-8', 
'af_ZA.UTF-8', 'agr_PE.UTF-8', 'ak_GH.UTF-8', 'am_ET.UTF-8', 'an_ES.UTF-8', 
'anp_IN.UTF-8', 'ar_AE.UTF-8', 'ar_BH.UTF-8', 'ar_DZ.UTF-8', 'ar_EG.UTF-8', 
'ar_IN.UTF-8', 'ar_IQ.UTF-8', 'ar_JO.UTF-8', 'ar_KW.UTF-8', 'ar_LB.UTF-8', 
'ar_LY.UTF-8', 'ar_MA.UTF-8', 'ar_OM.UTF-8', 'ar_QA.UTF-8', 'ar_SA.UTF-8', 
'ar_SD.UTF-8', 'ar_SS.UTF-8', 'ar_SY.UTF-8', 'ar_TN.UTF-8', 'ar_YE.UTF-8', 
'as_IN.UTF-8', 'ast_ES.UTF-8', 'ayc_PE.UTF-8', 'az_AZ.UTF-8', 'az_IR.UTF-8', 
'be_BY.UTF-8', 'be_BY.UTF-8@latin', 'bem_ZM.UTF-8', 'ber_DZ.UTF-8', 
'ber_MA.UTF-8', 'bg_BG.UTF-8', 'bhb_IN.UTF-8', 'bho_IN.UTF-8', 'bho_NP.UTF-8', 
'bi_VU.UTF-8', 'bn_BD.UTF-8', 'bn_IN.UTF-8', 'bo_CN.UTF-8', 'bo_IN.UTF-8', 
'br_FR.UTF-8', 'brx_IN.UTF-8', 'bs_BA.UTF-8', 'byn_ER.UTF-8', 'ca_AD.UTF-8', 
'ca_ES.UTF-8', 'ca_ES.UTF-8@valencia', 'ca_FR.UTF-8', 'ca_IT.UTF-8', 
'ce_RU.UTF-8', 'chr_US.UTF-8', 'ckb_IQ.UTF-8', 'cmn_TW.UTF-8', 'crh_RU.UTF-8', 
'crh_UA.UTF-8', 'cs_CZ.UTF-8', 
 'csb_PL.UTF-8', 'cv_RU.UTF-8', 'cy_GB.UTF-8', 'da_DK.UTF-8', 'de_AT.UTF-8', 
'de_BE.UTF-8', 'de_CH.UTF-8', 'de_DE.UTF-8', 'de_IT.UTF-8', 'de_LI.UTF-8', 
'de_LU.UTF-8', 'doi_IN.UTF-8', 'dsb_DE.UTF-8', 'dv_MV.UTF-8', 'dz_BT.UTF-8', 
'el_CY.UTF-8', 'el_GR.UTF-8', 'en_AG.UTF-8', 'en_AU.UTF-8', 'en_BW.UTF-8', 
'en_CA.UTF-8', 'en_DK.UTF-8', 'en_GB.UTF-8', 'en_HK.UTF-8', 'en_IE.UTF-8', 
'en_IL.UTF-8', 'en_IN.UTF-8', 'en_NG.UTF-8', 'en_NZ.UTF-8', 'en_PH.UTF-8', 
'en_SC.UTF-8', 'en_SG.UTF-8', 'en_US.UTF-8', 'en_ZA.UTF-8', 'en_ZM.UTF-8', 
'en_ZW.UTF-8', 'eo.UTF-8', 'es_AR.UTF-8', 'es_BO.UTF-8', 'es_CL.UTF-8', 
'es_CO.UTF-8', 'es_CR.UTF-8', 'es_CU.UTF-8', 'es_DO.UTF-8', 'es_EC.UTF-8', 
'es_ES.UTF-8', 'es_GT.UTF-8', 'es_HN.UTF-8', 'es_MX.UTF-8', 'es_NI.UTF-8', 
'es_PA.UTF-8', 'es_PE.UTF-8', 'es_PR.UTF-8', 'es_PY.UTF-8', 'es_SV.UTF-8', 
'es_US.UTF-8', 'es_UY.UTF-8', 'es_VE.UTF-8', 'et_EE.UTF-8', 'eu_ES.UTF-8', 
'fa_IR.UTF-8', 'ff_SN.UTF-8', 'fi_FI.UTF-8', 'fil_PH.UTF-8', 'fo_FO.UTF-8', 
'fr_BE.UTF-8', 'fr_CA
 .UTF-8', 'fr_CH.UTF-8', 'fr_FR.UTF-8', 'fr_HT.UTF-8', 'fr_LU.UTF-8', 
'fur_IT.UTF-8', 'fy_DE.UTF-8', 'fy_NL.UTF-8', 'ga_IE.UTF-8', 'gbm_IN.UTF-8', 
'gd_GB.UTF-8', 'gez_ER.UTF-8', 'gez_ER.UTF-8@abegede', 'gez_ET.UTF-8', 
'gez_ET.UTF-8@abegede', 'gl_ES.UTF-8', 'glk_IR.UTF-8', 'gu_IN.UTF-8', 
'gv_GB.UTF-8', 'ha_NG.UTF-8', 'hak_TW.UTF-8', 'he_IL.UTF-8', 'hi_IN.UTF-8', 
'hif_FJ.UTF-8', 'hne_IN.UTF-8', 'hr_HR.UTF-8', 'hsb_DE.UTF-8', 'ht_HT.UTF-8', 
'hu_HU.UTF-8', 'hy_AM.UTF-8', 'ia_FR.UTF-8', 'id_ID.UTF-8', 'ig_NG.UTF-8', 
'ik_CA.UTF-8', 'ilo_PH.UTF-8', 'is_IS.UTF-8', 'it_CH.UTF-8', 'it_IT.UTF-8', 
'iu_CA.UTF-8', 'iw_IL.UTF-8', 'ja_JP.UTF-8', 'ka_GE.UTF-8', 'kab_DZ.UTF-8', 
'kk_KZ.UTF-8', 'kl_GL.UTF-8', 'km_KH.UTF-8', 'kn_IN.UTF-8', 'ko_KR.UTF-8', 
'kok_IN.UTF-8', 'ks_IN.UTF-8', 'ks_IN.UTF-8@devanagari', 'ku_TR.UTF-8', 
'kv_RU.UTF-8', 'kw_GB.UTF-8', 'ky_KG.UTF-8', 'lb_LU.UTF-8', 'lg_UG.UTF-8', 
'li_BE.UTF-8', 'li_NL.UTF-8', 'lij_IT.UTF-8', 'ln_CD.UTF-8', 'lo_LA.UTF-8', 
'lt_LT.UTF-8', 'lv_LV.UTF-8', '
 lzh_TW.UTF-8', 'mag_IN.UTF-8', 'mai_IN.UTF-8', 'mai_NP.UTF-8', 'mdf_RU.UTF-8', 
'mfe_MU.UTF-8', 'mg_MG.UTF-8', 'mhr_RU.UTF-8', 'mi_NZ.UTF-8', 'miq_NI.UTF-8', 
'mjw_IN.UTF-8', 'mk_MK.UTF-8', 'ml_IN.UTF-8', 'mn_MN.UTF-8', 'mni_IN.UTF-8', 
'mnw_MM.UTF-8', 'mr_IN.UTF-8', 'ms_MY.UTF-8', 'mt_MT.UTF-8', 'my_MM.UTF-8', 
'nan_TW.UTF-8', 'nan_TW.UTF-8@latin', 'nb_NO.UTF-8', 'nds_DE.UTF-8', 
'nds_NL.UTF-8', 'ne_NP.UTF-8', 'nhn_MX.UTF-8', 'niu_NU.UTF-8', 'niu_NZ.UTF-8', 
'nl_AW.UTF-8', 'nl_BE.UTF-8', 'nl_NL.UTF-8', 'nn_NO.UTF-8', 'no_NO.UTF-8', 
'nr_ZA.UTF-8', 'nso_ZA.UTF-8', 'oc_FR.UTF-8', 'om_ET.UTF-8', 'om_KE.UTF-8', 
'or_IN.UTF-8', 'os_RU.UTF-8', 'pa_IN.UTF-8', 'pa_PK.UTF-8', 'pap_AN.UTF-8', 
'pap_AW.UTF-8', 'pap_CW.UTF-8', 'pl_PL.UTF-8', 'ps_AF.UTF-8', 'pt_BR.UTF-8', 
'pt_PT.UTF-8', 'quz_PE.UTF-8', 'raj_IN.UTF-8', 'rif_MA.UTF-8', 'ro_RO.UTF-8', 
'ru_RU.UTF-8', 'ru_UA.UTF-8', 'rw_RW.UTF-8', 'sa_IN.UTF-8', 'sah_RU.UTF-8', 
'sat_IN.UTF-8', 'sc_IT.UTF-8', 'sd_IN.UTF-8', 'sd_IN.UTF-8@devanagari', 
'se_NO.UT
 F-8', 'sgs_LT.UTF-8', 'shn_MM.UTF-8', 'shs_CA.UTF-8', 'si_LK.UTF-8', 
'sid_ET.UTF-8', 'sk_SK.UTF-8', 'sl_SI.UTF-8', 'sm_WS.UTF-8', 'so_DJ.UTF-8', 
'so_ET.UTF-8', 'so_KE.UTF-8', 'so_SO.UTF-8', 'sq_AL.UTF-8', 'sq_MK.UTF-8', 
'sr_ME.UTF-8', 'sr_ME.UTF-8@latin', 'sr_RS.UTF-8', 'sr_RS.UTF-8@latin', 
'ss_ZA.UTF-8', 'ssy_ER.UTF-8', 'st_ZA.UTF-8', 'sv_FI.UTF-8', 'sv_SE.UTF-8', 
'sw_KE.UTF-8', 'sw_TZ.UTF-8', 'syr.UTF-8', 'szl_PL.UTF-8', 'ta_IN.UTF-8', 
'ta_LK.UTF-8', 'ta_SG.UTF-8', 'tcy_IN.UTF-8', 'te_IN.UTF-8', 'tg_TJ.UTF-8', 
'th_TH.UTF-8', 'the_NP.UTF-8', 'ti_ER.UTF-8', 'ti_ET.UTF-8', 'tig_ER.UTF-8', 
'tk_TM.UTF-8', 'tl_PH.UTF-8', 'tn_BW.UTF-8', 'tn_ZA.UTF-8', 'to_TO.UTF-8', 
'tok.UTF-8', 'tpi_PG.UTF-8', 'tr_CY.UTF-8', 'tr_TR.UTF-8', 'ts_ZA.UTF-8', 
'tt_RU.UTF-8', 'tt_RU.UTF-8@iqtelif', 'ug_CN.UTF-8', 'uk_UA.UTF-8', 
'unm_US.UTF-8', 'ur_IN.UTF-8', 'ur_PK.UTF-8', 'uz_UZ.UTF-8', 
'uz_UZ.UTF-8@cyrillic', 've_ZA.UTF-8', 'vi_VN.UTF-8', 'wa_BE.UTF-8', 
'wae_CH.UTF-8', 'wal_ET.UTF-8', 'wo_SN.UTF-8', 'xh_ZA.U
 TF-8', 'yi_US.UTF-8', 'yo_NG.UTF-8', 'yue_HK.UTF-8', 'yuw_PG.UTF-8', 
'zh_CN.UTF-8', 'zh_HK.UTF-8', 'zh_MO.UTF-8', 'zh_SG.UTF-8', 'zh_TW.UTF-8', 
'zu_ZA.UTF-8']
+    ['aa_DJ.UTF-8', 'aa_ER.UTF-8', 'aa_ET.UTF-8', 'ab_GE.UTF-8', 
'af_ZA.UTF-8', 'agr_PE.UTF-8', 'ak_GH.UTF-8', 'am_ET.UTF-8', 'an_ES.UTF-8', 
'anp_IN.UTF-8', 'ar_AE.UTF-8', 'ar_BH.UTF-8', 'ar_DZ.UTF-8', 'ar_EG.UTF-8', 
'ar_IN.UTF-8', 'ar_IQ.UTF-8', 'ar_JO.UTF-8', 'ar_KW.UTF-8', 'ar_LB.UTF-8', 
'ar_LY.UTF-8', 'ar_MA.UTF-8', 'ar_OM.UTF-8', 'ar_QA.UTF-8', 'ar_SA.UTF-8', 
'ar_SD.UTF-8', 'ar_SS.UTF-8', 'ar_SY.UTF-8', 'ar_TN.UTF-8', 'ar_YE.UTF-8', 
'as_IN.UTF-8', 'ast_ES.UTF-8', 'ayc_PE.UTF-8', 'az_AZ.UTF-8', 'az_IR.UTF-8', 
'be_BY.UTF-8', 'be_BY.UTF-8@latin', 'bem_ZM.UTF-8', 'ber_DZ.UTF-8', 
'ber_MA.UTF-8', 'bg_BG.UTF-8', 'bhb_IN.UTF-8', 'bho_IN.UTF-8', 'bho_NP.UTF-8', 
'bi_VU.UTF-8', 'bn_BD.UTF-8', 'bn_IN.UTF-8', 'bo_CN.UTF-8', 'bo_IN.UTF-8', 
'br_FR.UTF-8', 'brx_IN.UTF-8', 'bs_BA.UTF-8', 'byn_ER.UTF-8', 'ca_AD.UTF-8', 
'ca_ES.UTF-8', 'ca_ES.UTF-8@valencia', 'ca_FR.UTF-8', 'ca_IT.UTF-8', 
'ce_RU.UTF-8', 'chr_US.UTF-8', 'ckb_IQ.UTF-8', 'cmn_TW.UTF-8', 'crh_RU.UTF-8', 
'crh_UA.UTF-8', 'cs_CZ.UTF-8', 
 'csb_PL.UTF-8', 'cv_RU.UTF-8', 'cy_GB.UTF-8', 'da_DK.UTF-8', 'de_AT.UTF-8', 
'de_BE.UTF-8', 'de_CH.UTF-8', 'de_DE.UTF-8', 'de_IT.UTF-8', 'de_LI.UTF-8', 
'de_LU.UTF-8', 'doi_IN.UTF-8', 'dsb_DE.UTF-8', 'dv_MV.UTF-8', 'dz_BT.UTF-8', 
'el_CY.UTF-8', 'el_GR.UTF-8', 'en_AG.UTF-8', 'en_AU.UTF-8', 'en_BW.UTF-8', 
'en_CA.UTF-8', 'en_DK.UTF-8', 'en_GB.UTF-8', 'en_HK.UTF-8', 'en_IE.UTF-8', 
'en_IL.UTF-8', 'en_IN.UTF-8', 'en_NG.UTF-8', 'en_NZ.UTF-8', 'en_PH.UTF-8', 
'en_SC.UTF-8', 'en_SG.UTF-8', 'en_US.UTF-8', 'en_ZA.UTF-8', 'en_ZM.UTF-8', 
'en_ZW.UTF-8', 'eo.UTF-8', 'es_AR.UTF-8', 'es_BO.UTF-8', 'es_CL.UTF-8', 
'es_CO.UTF-8', 'es_CR.UTF-8', 'es_CU.UTF-8', 'es_DO.UTF-8', 'es_EC.UTF-8', 
'es_ES.UTF-8', 'es_GT.UTF-8', 'es_HN.UTF-8', 'es_MX.UTF-8', 'es_NI.UTF-8', 
'es_PA.UTF-8', 'es_PE.UTF-8', 'es_PR.UTF-8', 'es_PY.UTF-8', 'es_SV.UTF-8', 
'es_US.UTF-8', 'es_UY.UTF-8', 'es_VE.UTF-8', 'et_EE.UTF-8', 'eu_ES.UTF-8', 
'fa_IR.UTF-8', 'ff_SN.UTF-8', 'fi_FI.UTF-8', 'fil_PH.UTF-8', 'fo_FO.UTF-8', 
'fr_BE.UTF-8', 'fr_CA
 .UTF-8', 'fr_CH.UTF-8', 'fr_FR.UTF-8', 'fr_HT.UTF-8', 'fr_LU.UTF-8', 
'fur_IT.UTF-8', 'fy_DE.UTF-8', 'fy_NL.UTF-8', 'ga_IE.UTF-8', 'gbm_IN.UTF-8', 
'gd_GB.UTF-8', 'gez_ER.UTF-8', 'gez_ER.UTF-8@abegede', 'gez_ET.UTF-8', 
'gez_ET.UTF-8@abegede', 'gl_ES.UTF-8', 'glk_IR.UTF-8', 'gu_IN.UTF-8', 
'gv_GB.UTF-8', 'ha_NG.UTF-8', 'hak_TW.UTF-8', 'he_IL.UTF-8', 'hi_IN.UTF-8', 
'hif_FJ.UTF-8', 'hne_IN.UTF-8', 'hr_HR.UTF-8', 'hsb_DE.UTF-8', 'ht_HT.UTF-8', 
'hu_HU.UTF-8', 'hy_AM.UTF-8', 'ia_FR.UTF-8', 'id_ID.UTF-8', 'ig_NG.UTF-8', 
'ik_CA.UTF-8', 'ilo_PH.UTF-8', 'is_IS.UTF-8', 'it_CH.UTF-8', 'it_IT.UTF-8', 
'iu_CA.UTF-8', 'iw_IL.UTF-8', 'ja_JP.UTF-8', 'ka_GE.UTF-8', 'kab_DZ.UTF-8', 
'kk_KZ.UTF-8', 'kl_GL.UTF-8', 'km_KH.UTF-8', 'kn_IN.UTF-8', 'ko_KR.UTF-8', 
'kok_IN.UTF-8', 'ks_IN.UTF-8', 'ks_IN.UTF-8@devanagari', 'ku_TR.UTF-8', 
'kv_RU.UTF-8', 'kw_GB.UTF-8', 'ky_KG.UTF-8', 'lb_LU.UTF-8', 'lg_UG.UTF-8', 
'li_BE.UTF-8', 'li_NL.UTF-8', 'lij_IT.UTF-8', 'ln_CD.UTF-8', 'lo_LA.UTF-8', 
'lt_LT.UTF-8', 'lv_LV.UTF-8', '
 lzh_TW.UTF-8', 'mag_IN.UTF-8', 'mai_IN.UTF-8', 'mai_NP.UTF-8', 'mdf_RU.UTF-8', 
'mfe_MU.UTF-8', 'mg_MG.UTF-8', 'mhr_RU.UTF-8', 'mi_NZ.UTF-8', 'miq_NI.UTF-8', 
'mjw_IN.UTF-8', 'mk_MK.UTF-8', 'ml_IN.UTF-8', 'mn_MN.UTF-8', 'mni_IN.UTF-8', 
'mnw_MM.UTF-8', 'mr_IN.UTF-8', 'ms_MY.UTF-8', 'mt_MT.UTF-8', 'my_MM.UTF-8', 
'nan_TW.UTF-8', 'nan_TW.UTF-8@latin', 'nb_NO.UTF-8', 'nds_DE.UTF-8', 
'nds_NL.UTF-8', 'ne_NP.UTF-8', 'nhn_MX.UTF-8', 'niu_NU.UTF-8', 'niu_NZ.UTF-8', 
'nl_AW.UTF-8', 'nl_BE.UTF-8', 'nl_NL.UTF-8', 'nn_NO.UTF-8', 'no_NO.UTF-8', 
'nr_ZA.UTF-8', 'nso_ZA.UTF-8', 'oc_FR.UTF-8', 'om_ET.UTF-8', 'om_KE.UTF-8', 
'or_IN.UTF-8', 'os_RU.UTF-8', 'pa_IN.UTF-8', 'pa_PK.UTF-8', 'pap_AN.UTF-8', 
'pap_AW.UTF-8', 'pap_CW.UTF-8', 'pl_PL.UTF-8', 'ps_AF.UTF-8', 'pt_BR.UTF-8', 
'pt_PT.UTF-8', 'quz_PE.UTF-8', 'raj_IN.UTF-8', 'rif_MA.UTF-8', 'ro_RO.UTF-8', 
'ru_RU.UTF-8', 'ru_UA.UTF-8', 'rw_RW.UTF-8', 'sa_IN.UTF-8', 'sah_RU.UTF-8', 
'sat_IN.UTF-8', 'sc_IT.UTF-8', 'scn_IT.UTF-8', 'sd_IN.UTF-8', 
'sd_IN.UTF-8@devana
 gari', 'se_NO.UTF-8', 'sgs_LT.UTF-8', 'shn_MM.UTF-8', 'shs_CA.UTF-8', 
'si_LK.UTF-8', 'sid_ET.UTF-8', 'sk_SK.UTF-8', 'sl_SI.UTF-8', 'sm_WS.UTF-8', 
'so_DJ.UTF-8', 'so_ET.UTF-8', 'so_KE.UTF-8', 'so_SO.UTF-8', 'sq_AL.UTF-8', 
'sq_MK.UTF-8', 'sr_ME.UTF-8', 'sr_ME.UTF-8@latin', 'sr_RS.UTF-8', 
'sr_RS.UTF-8@latin', 'ss_ZA.UTF-8', 'ssy_ER.UTF-8', 'st_ZA.UTF-8', 
'sv_FI.UTF-8', 'sv_SE.UTF-8', 'sw_KE.UTF-8', 'sw_TZ.UTF-8', 'syr.UTF-8', 
'szl_PL.UTF-8', 'ta_IN.UTF-8', 'ta_LK.UTF-8', 'ta_SG.UTF-8', 'tcy_IN.UTF-8', 
'te_IN.UTF-8', 'tg_TJ.UTF-8', 'th_TH.UTF-8', 'the_NP.UTF-8', 'ti_ER.UTF-8', 
'ti_ET.UTF-8', 'tig_ER.UTF-8', 'tk_TM.UTF-8', 'tl_PH.UTF-8', 'tn_BW.UTF-8', 
'tn_ZA.UTF-8', 'to_TO.UTF-8', 'tok.UTF-8', 'tpi_PG.UTF-8', 'tr_CY.UTF-8', 
'tr_TR.UTF-8', 'ts_ZA.UTF-8', 'tt_RU.UTF-8', 'tt_RU.UTF-8@iqtelif', 
'ug_CN.UTF-8', 'uk_UA.UTF-8', 'unm_US.UTF-8', 'ur_IN.UTF-8', 'ur_PK.UTF-8', 
'uz_UZ.UTF-8', 'uz_UZ.UTF-8@cyrillic', 've_ZA.UTF-8', 'vi_VN.UTF-8', 
'wa_BE.UTF-8', 'wae_CH.UTF-8', 'wal_ET.UTF-8', 'wo_SN.
 UTF-8', 'xh_ZA.UTF-8', 'yi_US.UTF-8', 'yo_NG.UTF-8', 'yue_HK.UTF-8', 
'yuw_PG.UTF-8', 'zh_CN.UTF-8', 'zh_HK.UTF-8', 'zh_MO.UTF-8', 'zh_SG.UTF-8', 
'zh_TW.UTF-8', 'zu_ZA.UTF-8']
     >>> print(list_all_keyboards())    # doctest: +NORMALIZE_WHITESPACE
     ['ad', 'af', 'af(fa-olpc)', 'af(ps)', 'af(ps-olpc)', 'af(uz)', 
'af(uz-olpc)', 'al', 'am', 'am(eastern)', 'am(eastern-alt)', 'am(phonetic)', 
'am(phonetic-alt)', 'am(western)', 'ara', 'ara(azerty)', 'ara(azerty_digits)', 
'ara(buckwalter)', 'ara(digits)', 'ara(qwerty)', 'ara(qwerty_digits)', 
'at(nodeadkeys)', 'az', 'az(cyrillic)', 'ba', 'bd', 'bd(probhat)', 'be', 
'be(oss)', 'bg', 'bg(bas_phonetic)', 'bg(phonetic)', 'br', 'brai', 
'brai(left_hand)', 'brai(right_hand)', 'bt', 'by', 'by(legacy)', 'ca', 
'ca(eng)', 'ca(ike)', 'ca(multi)', 'ca(multi-2gr)', 'ca(shs)', 'ch', 'ch(fr)', 
'cn', 'cn(tib)', 'cn(tib_asciinum)', 'cn(ug)', 'cz', 'cz(ucw)', 'de', 
'de(deadacute)', 'de(nodeadkeys)', 'de(ru)', 'dk', 'ee', 'es', 'es(ast)', 
'es(cat)', 'et', 'fi', 'fi(classic)', 'fi(nodeadkeys)', 'fo', 'fr', 'fr(geo)', 
'fr(latin9)', 'fr(oss)', 'gb', 'ge', 'ge(os)', 'gr', 'gr(extended)', 
'gr(nodeadkeys)', 'gr(polytonic)', 'gr(simple)', 'hr', 'hu', 'ie', 
'ie(CloGaelach)', 'ie(ogam)', 'il', 'il(biblical)', 'i
 l(lyx)', 'il(phonetic)', 'in', 'in(ben)', 'in(ben_baishakhi)', 
'in(ben_bornona)', 'in(ben_gitanjali)', 'in(ben_inscript)', 'in(ben_probhat)', 
'in(bolnagri)', 'in(deva)', 'in(eng)', 'in(guj)', 'in(guru)', 'in(hin-kagapa)', 
'in(hin-wx)', 'in(jhelum)', 'in(kan)', 'in(kan-kagapa)', 'in(mal)', 
'in(mal_enhanced)', 'in(mal_lalitha)', 'in(mar-kagapa)', 'in(ori)', 
'in(san-kagapa)', 'in(tam)', 'in(tam_tamilnet)', 'in(tam_tamilnet_TAB)', 
'in(tam_tamilnet_TSCII)', 'in(tam_tamilnet_with_tam_nums)', 'in(tel)', 
'in(tel-kagapa)', 'in(urd-phonetic)', 'in(urd-phonetic3)', 'in(urd-winkeys)', 
'iq', 'ir', 'ir(pes_keypad)', 'it', 'jp', 'jp(kana)', 'jp(mac)', 'ke', 'kg', 
'kg(phonetic)', 'kh', 'kr', 'kz', 'kz(kazrus)', 'kz(ruskaz)', 'la', 'la(stea)', 
'latam', 'lk', 'lk(tam_TAB)', 'lk(tam_unicode)', 'lt', 'lv', 'ma', 
'ma(french)', 'ma(tifinagh)', 'ma(tifinagh-alt)', 'ma(tifinagh-alt-phonetic)', 
'ma(tifinagh-extended)', 'ma(tifinagh-extended-phonetic)', 
'ma(tifinagh-phonetic)', 'me', 'me(cyrillic)', 'me(cyri
 llicalternatequotes)', 'me(cyrillicyz)', 'mk', 'mk(nodeadkeys)', 'mm', 'mn', 
'mt', 'mt(us)', 'mv', 'ng', 'ng(hausa)', 'ng(igbo)', 'ng(yoruba)', 'nl', 'no', 
'np', 'ph', 'ph(capewell-dvorak-bay)', 'ph(capewell-qwerf2k6-bay)', 
'ph(colemak-bay)', 'ph(dvorak-bay)', 'ph(qwerty-bay)', 'pk', 'pk(ara)', 
'pk(snd)', 'pk(urd-crulp)', 'pk(urd-nla)', 'pl', 'pl(ru_phonetic_dvorak)', 
'pt', 'ro', 'rs', 'rs(alternatequotes)', 'rs(latin)', 'rs(rue)', 'rs(yz)', 
'ru', 'ru(bak)', 'ru(chm)', 'ru(cv)', 'ru(dos)', 'ru(kom)', 'ru(legacy)', 
'ru(mac)', 'ru(os_legacy)', 'ru(os_winkeys)', 'ru(phonetic)', 
'ru(phonetic_winkeys)', 'ru(sah)', 'ru(srp)', 'ru(tt)', 'ru(typewriter)', 
'ru(typewriter-legacy)', 'ru(udm)', 'ru(xal)', 'se', 'se(nodeadkeys)', 
'se(rus)', 'se(rus_nodeadkeys)', 'se(swl)', 'si', 'sk', 'sn', 'sy', 'sy(syc)', 
'sy(syc_phonetic)', 'th', 'th(pat)', 'th(tis)', 'tj', 'tj(legacy)', 'tm', 'tr', 
'tr(crh)', 'tr(ku)', 'tz', 'ua', 'ua(homophonic)', 'ua(legacy)', 
'ua(phonetic)', 'ua(rstu)', 'ua(rstu_ru)', 'ua
 (typewriter)', 'ua(winkeys)', 'us', 'us(altgr-intl)', 'us(chr)', 'us(euro)', 
'us(intl)', 'us(rus)', 'uz', 'uz(latin)', 'vn', 'za']
     >>> print(list_all_territories())    # doctest: +NORMALIZE_WHITESPACE
@@ -2165,7 +2165,7 @@
     >>> print(list_all_timezones())    # doctest: +NORMALIZE_WHITESPACE
     ['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', 'Africa/Algiers', 
'Africa/Asmara', 'Africa/Bamako', 'Africa/Bangui', 'Africa/Banjul', 
'Africa/Bissau', 'Africa/Blantyre', 'Africa/Brazzaville', 'Africa/Bujumbura', 
'Africa/Cairo', 'Africa/Casablanca', 'Africa/Ceuta', 'Africa/Conakry', 
'Africa/Dakar', 'Africa/Dar_es_Salaam', 'Africa/Djibouti', 'Africa/Douala', 
'Africa/El_Aaiun', 'Africa/Freetown', 'Africa/Gaborone', 'Africa/Harare', 
'Africa/Johannesburg', 'Africa/Juba', 'Africa/Kampala', 'Africa/Khartoum', 
'Africa/Kigali', 'Africa/Kinshasa', 'Africa/Lagos', 'Africa/Libreville', 
'Africa/Lome', 'Africa/Luanda', 'Africa/Lubumbashi', 'Africa/Lusaka', 
'Africa/Malabo', 'Africa/Maputo', 'Africa/Maseru', 'Africa/Mbabane', 
'Africa/Mogadishu', 'Africa/Monrovia', 'Africa/Nairobi', 'Africa/Ndjamena', 
'Africa/Niamey', 'Africa/Nouakchott', 'Africa/Ouagadougou', 
'Africa/Porto-Novo', 'Africa/Sao_Tome', 'Africa/Tripoli', 'Africa/Tunis', 
'Africa/Windhoek', 'America/Adak', 'America/Anchorage'
 , 'America/Anguilla', 'America/Antigua', 'America/Araguaina', 
'America/Argentina/Buenos_Aires', 'America/Argentina/Catamarca', 
'America/Argentina/Cordoba', 'America/Argentina/Jujuy', 
'America/Argentina/La_Rioja', 'America/Argentina/Mendoza', 
'America/Argentina/Rio_Gallegos', 'America/Argentina/Salta', 
'America/Argentina/San_Juan', 'America/Argentina/San_Luis', 
'America/Argentina/Tucuman', 'America/Argentina/Ushuaia', 'America/Aruba', 
'America/Asuncion', 'America/Atikokan', 'America/Bahia', 
'America/Bahia_Banderas', 'America/Barbados', 'America/Belem', 
'America/Belize', 'America/Blanc-Sablon', 'America/Boa_Vista', 
'America/Bogota', 'America/Boise', 'America/Cambridge_Bay', 
'America/Campo_Grande', 'America/Cancun', 'America/Caracas', 'America/Cayenne', 
'America/Cayman', 'America/Chicago', 'America/Chihuahua', 'America/Costa_Rica', 
'America/Creston', 'America/Cuiaba', 'America/Curacao', 'America/Danmarkshavn', 
'America/Dawson', 'America/Dawson_Creek', 'America/Denver', 'America/Detroit
 ', 'America/Dominica', 'America/Edmonton', 'America/Eirunepe', 
'America/El_Salvador', 'America/Fortaleza', 'America/Galapagos', 
'America/Glace_Bay', 'America/Godthab', 'America/Goose_Bay', 
'America/Grand_Turk', 'America/Grenada', 'America/Guadeloupe', 
'America/Guatemala', 'America/Guayaquil', 'America/Guyana', 'America/Halifax', 
'America/Havana', 'America/Hermosillo', 'America/Indiana/Indianapolis', 
'America/Indiana/Knox', 'America/Indiana/Marengo', 
'America/Indiana/Petersburg', 'America/Indiana/Tell_City', 
'America/Indiana/Vevay', 'America/Indiana/Vincennes', 
'America/Indiana/Winamac', 'America/Inuvik', 'America/Iqaluit', 
'America/Jamaica', 'America/Juneau', 'America/Kentucky/Louisville', 
'America/Kentucky/Monticello', 'America/Kralendijk', 'America/La_Paz', 
'America/Lima', 'America/Los_Angeles', 'America/Lower_Princes', 
'America/Maceio', 'America/Managua', 'America/Manaus', 'America/Marigot', 
'America/Martinique', 'America/Matamoros', 'America/Mazatlan', 
'America/Menominee', 'Amer
 ica/Merida', 'America/Metlakatla', 'America/Mexico_City', 'America/Miquelon', 
'America/Moncton', 'America/Monterrey', 'America/Montevideo', 
'America/Montreal', 'America/Montserrat', 'America/Nassau', 'America/New_York', 
'America/Nipigon', 'America/Nome', 'America/Noronha', 
'America/North_Dakota/Beulah', 'America/North_Dakota/Center', 
'America/North_Dakota/New_Salem', 'America/Ojinaga', 'America/Panama', 
'America/Pangnirtung', 'America/Paramaribo', 'America/Phoenix', 
'America/Port-au-Prince', 'America/Port_of_Spain', 'America/Porto_Velho', 
'America/Puerto_Rico', 'America/Rainy_River', 'America/Rankin_Inlet', 
'America/Recife', 'America/Regina', 'America/Resolute', 'America/Rio_Branco', 
'America/Santa_Isabel', 'America/Santarem', 'America/Santiago', 
'America/Santo_Domingo', 'America/Sao_Paulo', 'America/Scoresbysund', 
'America/Shiprock', 'America/Sitka', 'America/St_Barthelemy', 
'America/St_Johns', 'America/St_Kitts', 'America/St_Lucia', 
'America/St_Thomas', 'America/St_Vincent', 'Amer
 ica/Swift_Current', 'America/Tegucigalpa', 'America/Thule', 
'America/Thunder_Bay', 'America/Tijuana', 'America/Toronto', 'America/Tortola', 
'America/Vancouver', 'America/Whitehorse', 'America/Winnipeg', 
'America/Yakutat', 'America/Yellowknife', 'Arctic/Longyearbyen', 'Asia/Aden', 
'Asia/Amman', 'Asia/Anadyr', 'Asia/Ashgabat', 'Asia/Baghdad', 'Asia/Bahrain', 
'Asia/Baku', 'Asia/Bangkok', 'Asia/Beirut', 'Asia/Bishkek', 'Asia/Brunei', 
'Asia/Choibalsan', 'Asia/Colombo', 'Asia/Damascus', 'Asia/Dhaka', 'Asia/Dili', 
'Asia/Dubai', 'Asia/Dushanbe', 'Asia/Famagusta', 'Asia/Gaza', 
'Asia/Ho_Chi_Minh', 'Asia/Hong_Kong', 'Asia/Hovd', 'Asia/Irkutsk', 
'Asia/Jakarta', 'Asia/Jayapura', 'Asia/Jerusalem', 'Asia/Kabul', 
'Asia/Kamchatka', 'Asia/Karachi', 'Asia/Kathmandu', 'Asia/Khandyga', 
'Asia/Kolkata', 'Asia/Krasnoyarsk', 'Asia/Kuala_Lumpur', 'Asia/Kuching', 
'Asia/Kuwait', 'Asia/Macau', 'Asia/Magadan', 'Asia/Manila', 'Asia/Muscat', 
'Asia/Nicosia', 'Asia/Novokuznetsk', 'Asia/Novosibirsk', 'Asia/Omsk', 'As
 ia/Oral', 'Asia/Phnom_Penh', 'Asia/Pyongyang', 'Asia/Qatar', 'Asia/Rangoon', 
'Asia/Riyadh', 'Asia/Sakhalin', 'Asia/Samarkand', 'Asia/Seoul', 
'Asia/Shanghai', 'Asia/Singapore', 'Asia/Taipei', 'Asia/Tashkent', 
'Asia/Tbilisi', 'Asia/Tehran', 'Asia/Thimphu', 'Asia/Tokyo', 
'Asia/Ulaanbaatar', 'Asia/Ust-Nera', 'Asia/Vientiane', 'Asia/Vladivostok', 
'Asia/Yakutsk', 'Asia/Yangon', 'Asia/Yekaterinburg', 'Asia/Yerevan', 
'Atlantic/Azores', 'Atlantic/Bermuda', 'Atlantic/Canary', 
'Atlantic/Cape_Verde', 'Atlantic/Faroe', 'Atlantic/Madeira', 
'Atlantic/Reykjavik', 'Atlantic/St_Helena', 'Atlantic/Stanley', 
'Australia/Adelaide', 'Australia/Brisbane', 'Australia/Broken_Hill', 
'Australia/Currie', 'Australia/Darwin', 'Australia/Eucla', 'Australia/Hobart', 
'Australia/Lindeman', 'Australia/Lord_Howe', 'Australia/Melbourne', 
'Australia/Perth', 'Australia/Sydney', 'Europe/Amsterdam', 'Europe/Andorra', 
'Europe/Athens', 'Europe/Belgrade', 'Europe/Berlin', 'Europe/Bratislava', 
'Europe/Brussels', 'Europe/Buchare
 st', 'Europe/Budapest', 'Europe/Busingen', 'Europe/Chisinau', 
'Europe/Copenhagen', 'Europe/Dublin', 'Europe/Gibraltar', 'Europe/Guernsey', 
'Europe/Helsinki', 'Europe/Isle_of_Man', 'Europe/Istanbul', 'Europe/Jersey', 
'Europe/Kaliningrad', 'Europe/Kiev', 'Europe/Lisbon', 'Europe/Ljubljana', 
'Europe/London', 'Europe/Luxembourg', 'Europe/Madrid', 'Europe/Malta', 
'Europe/Mariehamn', 'Europe/Minsk', 'Europe/Monaco', 'Europe/Moscow', 
'Europe/Oslo', 'Europe/Paris', 'Europe/Podgorica', 'Europe/Prague', 
'Europe/Riga', 'Europe/Rome', 'Europe/Samara', 'Europe/San_Marino', 
'Europe/Sarajevo', 'Europe/Simferopol', 'Europe/Skopje', 'Europe/Sofia', 
'Europe/Stockholm', 'Europe/Tallinn', 'Europe/Tirane', 'Europe/Uzhgorod', 
'Europe/Vaduz', 'Europe/Vatican', 'Europe/Vienna', 'Europe/Vilnius', 
'Europe/Volgograd', 'Europe/Warsaw', 'Europe/Zagreb', 'Europe/Zaporozhye', 
'Europe/Zurich', 'Indian/Antananarivo', 'Indian/Chagos', 'Indian/Christmas', 
'Indian/Cocos', 'Indian/Comoro', 'Indian/Mahe', 'Indian/Maldiv
 es', 'Indian/Mauritius', 'Indian/Mayotte', 'Indian/Reunion', 'Pacific/Apia', 
'Pacific/Auckland', 'Pacific/Chatham', 'Pacific/Chuuk', 'Pacific/Easter', 
'Pacific/Efate', 'Pacific/Fakaofo', 'Pacific/Fiji', 'Pacific/Funafuti', 
'Pacific/Guadalcanal', 'Pacific/Guam', 'Pacific/Honolulu', 
'Pacific/Kiritimati', 'Pacific/Kwajalein', 'Pacific/Majuro', 'Pacific/Midway', 
'Pacific/Nauru', 'Pacific/Niue', 'Pacific/Norfolk', 'Pacific/Noumea', 
'Pacific/Pago_Pago', 'Pacific/Palau', 'Pacific/Pitcairn', 
'Pacific/Port_Moresby', 'Pacific/Rarotonga', 'Pacific/Saipan', 
'Pacific/Tahiti', 'Pacific/Tongatapu', 'Pacific/Wake', 'Pacific/Wallis', 
'US/Pacific']
     >>> print(list_all_scripts())    # doctest: +NORMALIZE_WHITESPACE
-    ['Adlm', 'Arab', 'Armn', 'Beng', 'Bhks', 'Cakm', 'Cans', 'Cher', 'Copt', 
'Cprt', 'Cyrl', 'Cyrs', 'Deva', 'Elba', 'Ethi', 'Geor', 'Glag', 'Gran', 'Grek', 
'Gujr', 'Guru', 'Hang', 'Hani', 'Hans', 'Hant', 'Hebr', 'Hira', 'Hung', 'Java', 
'Jpan', 'Kana', 'Khmr', 'Knda', 'Kore', 'Lana', 'Laoo', 'Latin', 'Latn', 
'Linb', 'Mahj', 'Marc', 'Mlym', 'Modi', 'Mong', 'Mtei', 'Mymr', 'Newa', 'Nkoo', 
'Olck', 'Orya', 'Osge', 'Osma', 'Perm', 'Phag', 'Shrd', 'Sidd', 'Sinh', 'Sund', 
'Syrc', 'Takr', 'Talu', 'Taml', 'Tang', 'Telu', 'Tfng', 'Tglg', 'Thaa', 'Thai', 
'Tibt', 'Tirh', 'Vaii', 'Yiii']
+    ['Adlm', 'Arab', 'Armn', 'Beng', 'Bhks', 'Cakm', 'Cans', 'Cher', 'Copt', 
'Cprt', 'Cyrl', 'Cyrs', 'Deva', 'Dsrt', 'Elba', 'Ethi', 'Geor', 'Glag', 'Gran', 
'Grek', 'Gujr', 'Guru', 'Hang', 'Hani', 'Hans', 'Hant', 'Hebr', 'Hira', 'Hmnp', 
'Hung', 'Java', 'Jpan', 'Kana', 'Khmr', 'Knda', 'Kore', 'Lana', 'Laoo', 
'Latin', 'Latn', 'Linb', 'Mahj', 'Marc', 'Mlym', 'Modi', 'Mong', 'Mtei', 
'Mymr', 'Newa', 'Nkoo', 'Olck', 'Orya', 'Osge', 'Osma', 'Perm', 'Phag', 'Rohg', 
'Shaw', 'Shrd', 'Sidd', 'Sinh', 'Sund', 'Syrc', 'Takr', 'Talu', 'Taml', 'Tang', 
'Tavt', 'Telu', 'Tfng', 'Tglg', 'Thaa', 'Thai', 'Tibt', 'Tirh', 'Vaii', 'Yiii']
     >>> print(list_all_input_methods())    # doctest: +NORMALIZE_WHITESPACE
     ['ibus/anthy', 'ibus/chewing', 'ibus/hangul', 'ibus/kkc', 
'ibus/libpinyin', 'ibus/libzhuyin', 'ibus/m17n:ar:kbd', 
'ibus/m17n:as:inscript2', 'ibus/m17n:bn:inscript2', 
'ibus/m17n:brx:inscript2-deva', 'ibus/m17n:doi:inscript2-deva', 
'ibus/m17n:gu:inscript2', 'ibus/m17n:hi:inscript2', 'ibus/m17n:kn:inscript2', 
'ibus/m17n:kok:inscript2-deva', 'ibus/m17n:ks:inscript2-deva', 
'ibus/m17n:ks:kbd', 'ibus/m17n:mai:inscript2', 'ibus/m17n:ml:inscript2', 
'ibus/m17n:mni:inscript2-beng', 'ibus/m17n:mr:inscript2', 
'ibus/m17n:ne:inscript2-deva', 'ibus/m17n:or:inscript2', 
'ibus/m17n:pa:inscript2-guru', 'ibus/m17n:sa:inscript2', 
'ibus/m17n:sat:inscript2-deva', 'ibus/m17n:sd:inscript2-deva', 
'ibus/m17n:ta:inscript2', 'ibus/m17n:te:inscript2', 'ibus/m17n:ur:phonetic', 
'ibus/m17n:vi:telex', 'ibus/table:cangjie5']
     >>> print(list_all_console_fonts())    # doctest: +NORMALIZE_WHITESPACE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langtable-0.0.66/tools/list-missing-from-cldr 
new/langtable-0.0.67/tools/list-missing-from-cldr
--- old/langtable-0.0.66/tools/list-missing-from-cldr   1970-01-01 
01:00:00.000000000 +0100
+++ new/langtable-0.0.67/tools/list-missing-from-cldr   2024-05-23 
17:25:59.000000000 +0200
@@ -0,0 +1,42 @@
+#! /usr/bin/python3
+
+from typing import Set
+import os
+import sys
+import re
+import glob
+
+# pylint: disable=wrong-import-order
+sys.path.insert(0, "/local/mfabian/src/langtable")
+# pylint: disable=import-error
+import langtable # type: ignore
+# pylint: enable=import-error
+sys.path.pop(0)
+# pylint: enable=wrong-import-order
+
+CLDR_SOURCE_DIR = '/local/mfabian/src/cldr'
+ALL_LANGUAGES = langtable.list_all_languages()
+ALL_SCRIPTS = langtable.list_all_scripts()
+ALL_TERRITORIES = langtable.list_all_territories()
+MISSING_LANGUAGES: Set[str] = set()
+MISSING_SCRIPTS: Set[str] = set()
+MISSING_TERRITORIES: Set[str] = set()
+
+for cldr_file in sorted(glob.glob(
+        os.path.join(CLDR_SOURCE_DIR, 'common/main', '*.xml'))):
+    cldr_locale_id = cldr_file.split('/')[-1].split('.')[0]
+    locale = langtable.parse_locale(cldr_locale_id)
+    #print(f'id={cldr_locale_id} language={locale.language} 
script={locale.script} territory={locale.territory} variant={locale.variant}')
+    if locale.language and locale.language not in ALL_LANGUAGES:
+        MISSING_LANGUAGES.add(locale.language)
+    if locale.script and locale.script not in ALL_SCRIPTS:
+        MISSING_SCRIPTS.add(locale.script)
+    if locale.territory and locale.territory not in ALL_TERRITORIES:
+        MISSING_TERRITORIES.add(locale.territory)
+
+print(f'{langtable.info()}')
+print(f'Missing languages: {sorted(MISSING_LANGUAGES)}')
+print(f'Missing scripts: {sorted(MISSING_SCRIPTS)}')
+print(f'Missing territories: {sorted(MISSING_TERRITORIES)}')
+
+

Reply via email to