done
This commit is contained in:
104
lib/python3.11/site-packages/babel/localtime/_unix.py
Normal file
104
lib/python3.11/site-packages/babel/localtime/_unix.py
Normal file
@ -0,0 +1,104 @@
|
||||
import datetime
|
||||
import os
|
||||
import re
|
||||
|
||||
from babel.localtime._helpers import (
|
||||
_get_tzinfo,
|
||||
_get_tzinfo_from_file,
|
||||
_get_tzinfo_or_raise,
|
||||
)
|
||||
|
||||
|
||||
def _tz_from_env(tzenv: str) -> datetime.tzinfo:
|
||||
if tzenv[0] == ':':
|
||||
tzenv = tzenv[1:]
|
||||
|
||||
# TZ specifies a file
|
||||
if os.path.exists(tzenv):
|
||||
return _get_tzinfo_from_file(tzenv)
|
||||
|
||||
# TZ specifies a zoneinfo zone.
|
||||
return _get_tzinfo_or_raise(tzenv)
|
||||
|
||||
|
||||
def _get_localzone(_root: str = '/') -> datetime.tzinfo:
|
||||
"""Tries to find the local timezone configuration.
|
||||
This method prefers finding the timezone name and passing that to
|
||||
zoneinfo or pytz, over passing in the localtime file, as in the later
|
||||
case the zoneinfo name is unknown.
|
||||
The parameter _root makes the function look for files like /etc/localtime
|
||||
beneath the _root directory. This is primarily used by the tests.
|
||||
In normal usage you call the function without parameters.
|
||||
"""
|
||||
|
||||
tzenv = os.environ.get('TZ')
|
||||
if tzenv:
|
||||
return _tz_from_env(tzenv)
|
||||
|
||||
# This is actually a pretty reliable way to test for the local time
|
||||
# zone on operating systems like OS X. On OS X especially this is the
|
||||
# only one that actually works.
|
||||
try:
|
||||
link_dst = os.readlink('/etc/localtime')
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
pos = link_dst.find('/zoneinfo/')
|
||||
if pos >= 0:
|
||||
# On occasion, the `/etc/localtime` symlink has a double slash, e.g.
|
||||
# "/usr/share/zoneinfo//UTC", which would make `zoneinfo.ZoneInfo`
|
||||
# complain (no absolute paths allowed), and we'd end up returning
|
||||
# `None` (as a fix for #1092).
|
||||
# Instead, let's just "fix" the double slash symlink by stripping
|
||||
# leading slashes before passing the assumed zone name forward.
|
||||
zone_name = link_dst[pos + 10:].lstrip("/")
|
||||
tzinfo = _get_tzinfo(zone_name)
|
||||
if tzinfo is not None:
|
||||
return tzinfo
|
||||
|
||||
# Now look for distribution specific configuration files
|
||||
# that contain the timezone name.
|
||||
tzpath = os.path.join(_root, 'etc/timezone')
|
||||
if os.path.exists(tzpath):
|
||||
with open(tzpath, 'rb') as tzfile:
|
||||
data = tzfile.read()
|
||||
|
||||
# Issue #3 in tzlocal was that /etc/timezone was a zoneinfo file.
|
||||
# That's a misconfiguration, but we need to handle it gracefully:
|
||||
if data[:5] != b'TZif2':
|
||||
etctz = data.strip().decode()
|
||||
# Get rid of host definitions and comments:
|
||||
if ' ' in etctz:
|
||||
etctz, dummy = etctz.split(' ', 1)
|
||||
if '#' in etctz:
|
||||
etctz, dummy = etctz.split('#', 1)
|
||||
|
||||
return _get_tzinfo_or_raise(etctz.replace(' ', '_'))
|
||||
|
||||
# CentOS has a ZONE setting in /etc/sysconfig/clock,
|
||||
# OpenSUSE has a TIMEZONE setting in /etc/sysconfig/clock and
|
||||
# Gentoo has a TIMEZONE setting in /etc/conf.d/clock
|
||||
# We look through these files for a timezone:
|
||||
timezone_re = re.compile(r'\s*(TIME)?ZONE\s*=\s*"(?P<etctz>.+)"')
|
||||
|
||||
for filename in ('etc/sysconfig/clock', 'etc/conf.d/clock'):
|
||||
tzpath = os.path.join(_root, filename)
|
||||
if not os.path.exists(tzpath):
|
||||
continue
|
||||
with open(tzpath) as tzfile:
|
||||
for line in tzfile:
|
||||
match = timezone_re.match(line)
|
||||
if match is not None:
|
||||
# We found a timezone
|
||||
etctz = match.group("etctz")
|
||||
return _get_tzinfo_or_raise(etctz.replace(' ', '_'))
|
||||
|
||||
# No explicit setting existed. Use localtime
|
||||
for filename in ('etc/localtime', 'usr/local/etc/localtime'):
|
||||
tzpath = os.path.join(_root, filename)
|
||||
|
||||
if not os.path.exists(tzpath):
|
||||
continue
|
||||
return _get_tzinfo_from_file(tzpath)
|
||||
|
||||
raise LookupError('Can not find any timezone configuration')
|
Reference in New Issue
Block a user