mirror of https://github.com/caronc/apprise
Handled Py11 getdefaultlocale() deprecation warnings (#754)
parent
e46f8fec1d
commit
5fd568fa35
|
@ -33,6 +33,8 @@
|
|||
import ctypes
|
||||
import locale
|
||||
import contextlib
|
||||
import os
|
||||
import re
|
||||
from os.path import join
|
||||
from os.path import dirname
|
||||
from os.path import abspath
|
||||
|
@ -95,6 +97,17 @@ class AppriseLocale:
|
|||
|
||||
"""
|
||||
|
||||
# Locale regular expression
|
||||
_local_re = re.compile(
|
||||
r'^\s*(?P<lang>[a-z]{2})([_:]((?P<country>[a-z]{2}))?'
|
||||
r'(\.(?P<enc>[a-z0-9]+))?|.+)?', re.IGNORECASE)
|
||||
|
||||
# Define our default encoding
|
||||
_default_encoding = 'utf-8'
|
||||
|
||||
# Define our default language
|
||||
_default_language = 'en'
|
||||
|
||||
def __init__(self, language=None):
|
||||
"""
|
||||
Initializes our object, if a language is specified, then we
|
||||
|
@ -181,7 +194,7 @@ class AppriseLocale:
|
|||
@staticmethod
|
||||
def detect_language(lang=None, detect_fallback=True):
|
||||
"""
|
||||
returns the language (if it's retrievable)
|
||||
Returns the language (if it's retrievable)
|
||||
"""
|
||||
# We want to only use the 2 character version of this language
|
||||
# hence en_CA becomes en, en_US becomes en.
|
||||
|
@ -190,6 +203,17 @@ class AppriseLocale:
|
|||
# no detection enabled; we're done
|
||||
return None
|
||||
|
||||
# Posix lookup
|
||||
lookup = os.environ.get
|
||||
localename = None
|
||||
for variable in ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'):
|
||||
localename = lookup(variable, None)
|
||||
if localename:
|
||||
result = AppriseLocale._local_re.match(localename)
|
||||
if result and result.group('lang'):
|
||||
return result.group('lang').lower()
|
||||
|
||||
# Windows handling
|
||||
if hasattr(ctypes, 'windll'):
|
||||
windll = ctypes.windll.kernel32
|
||||
try:
|
||||
|
@ -203,11 +227,12 @@ class AppriseLocale:
|
|||
# Fallback to posix detection
|
||||
pass
|
||||
|
||||
# Linux Handling
|
||||
try:
|
||||
# Detect language
|
||||
lang = locale.getdefaultlocale()[0]
|
||||
# Acquire our locale
|
||||
lang = locale.getlocale()[0]
|
||||
|
||||
except ValueError as e:
|
||||
except TypeError as e:
|
||||
# This occurs when an invalid locale was parsed from the
|
||||
# environment variable. While we still return None in this
|
||||
# case, we want to better notify the end user of this. Users
|
||||
|
@ -217,11 +242,6 @@ class AppriseLocale:
|
|||
'Language detection failure / {}'.format(str(e)))
|
||||
return None
|
||||
|
||||
except TypeError:
|
||||
# None is returned if the default can't be determined
|
||||
# we're done in this case
|
||||
return None
|
||||
|
||||
return None if not lang else lang[0:2].lower()
|
||||
|
||||
def __getstate__(self):
|
||||
|
|
|
@ -36,6 +36,7 @@ import json
|
|||
import contextlib
|
||||
import os
|
||||
import hashlib
|
||||
import locale
|
||||
from itertools import chain
|
||||
from os.path import expanduser
|
||||
from functools import reduce
|
||||
|
@ -1488,7 +1489,7 @@ def environ(*remove, **update):
|
|||
|
||||
# Create a backup of our environment for restoration purposes
|
||||
env_orig = os.environ.copy()
|
||||
|
||||
loc_orig = locale.getlocale()
|
||||
try:
|
||||
os.environ.update(update)
|
||||
[os.environ.pop(k, None) for k in remove]
|
||||
|
@ -1497,6 +1498,13 @@ def environ(*remove, **update):
|
|||
finally:
|
||||
# Restore our snapshot
|
||||
os.environ = env_orig.copy()
|
||||
try:
|
||||
# Restore locale
|
||||
locale.setlocale(locale.LC_ALL, loc_orig)
|
||||
|
||||
except locale.Error:
|
||||
# Thrown in py3.6
|
||||
pass
|
||||
|
||||
|
||||
def apply_template(template, app_mode=TemplateType.RAW, **kwargs):
|
||||
|
|
|
@ -144,6 +144,7 @@ def test_detect_language_windows_users():
|
|||
|
||||
if hasattr(ctypes, 'windll'):
|
||||
from ctypes import windll
|
||||
|
||||
else:
|
||||
windll = mock.Mock()
|
||||
# 4105 = en_CA
|
||||
|
@ -164,18 +165,17 @@ def test_detect_language_windows_users():
|
|||
assert AppriseLocale.AppriseLocale.detect_language() == 'en'
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.platform == "win32", reason="Does not work on Windows")
|
||||
def test_detect_language_windows_users_croaks_please_review():
|
||||
def test_detect_language_using_env():
|
||||
"""
|
||||
When enabling CI testing on Windows, those tests did not produce the
|
||||
correct results. They may want to be reviewed.
|
||||
Test the reading of information from an environment variable
|
||||
"""
|
||||
|
||||
# The below accesses the windows fallback code and fail
|
||||
# then it will resort to the environment variables.
|
||||
with environ('LANG', 'LANGUAGE', 'LC_ALL', 'LC_CTYPE'):
|
||||
# Language can't be detected
|
||||
assert AppriseLocale.AppriseLocale.detect_language() is None
|
||||
# Language can now be detected in this case
|
||||
assert isinstance(
|
||||
AppriseLocale.AppriseLocale.detect_language(), str)
|
||||
|
||||
# Detect French language.
|
||||
with environ('LANGUAGE', 'LC_ALL', 'LC_CTYPE', LANG="fr_CA"):
|
||||
|
@ -187,23 +187,28 @@ def test_detect_language_windows_users_croaks_please_review():
|
|||
# dropped, but just to ensure this issue does not come back, we keep
|
||||
# this test:
|
||||
with environ(*list(os.environ.keys()), LC_CTYPE="UTF-8"):
|
||||
assert AppriseLocale.AppriseLocale.detect_language() is None
|
||||
assert isinstance(AppriseLocale.AppriseLocale.detect_language(), str)
|
||||
|
||||
# Test with absolutely no environment variables what-so-ever
|
||||
with environ(*list(os.environ.keys())):
|
||||
assert AppriseLocale.AppriseLocale.detect_language() is None
|
||||
assert isinstance(AppriseLocale.AppriseLocale.detect_language(), str)
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.platform == "win32", reason="Does not work on Windows")
|
||||
@mock.patch('locale.getdefaultlocale')
|
||||
def test_detect_language_defaultlocale(mock_getlocale):
|
||||
@mock.patch('locale.getlocale')
|
||||
def test_detect_language_locale(mock_getlocale):
|
||||
"""
|
||||
API: Apprise() Default locale detection
|
||||
|
||||
"""
|
||||
# Handle case where getdefaultlocale() can't be detected
|
||||
# Handle case where getlocale() can't be detected
|
||||
mock_getlocale.return_value = None
|
||||
assert AppriseLocale.AppriseLocale.detect_language() is None
|
||||
with environ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'):
|
||||
assert AppriseLocale.AppriseLocale.detect_language() is None
|
||||
|
||||
mock_getlocale.return_value = (None, None)
|
||||
with environ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'):
|
||||
assert AppriseLocale.AppriseLocale.detect_language() is None
|
||||
|
||||
# if detect_language and windows env fail us, then we don't
|
||||
# set up a default language on first load
|
||||
|
|
Loading…
Reference in New Issue