dl1wjd2's picture
Upload folder using huggingface_hub (part 4)
bbae060 verified
Raw History Blame Contribute Delete
7.97 kB
# -*- coding: utf-8 -*-
"""
The ``dateutil.zoneinfo`` module was originally designed to work with a tarball
shipped with ``dateutil``. Since ``dateutil`` now uses data from the same
sources as :py:mod:`zoneinfo`, this module is no longer necessary.
.. caution::
This module is deprecated, and its functionality has been dramatically
curtailed. It is recommended that you adopt the standard library module
:py:mod:`zoneinfo` or :func:`dateutil.tz.gettz` instead.
"""
import json
import sys
import warnings
from tarfile import TarFile
import six
from dateutil import _tzdata_impl
from dateutil.tz import tzfile as _tzfile
__all__ = ["get_zonefile_instance", "gettz", "gettz_db_metadata"]
ZONEFILENAME = None
METADATA_FN = 'METADATA'
def _importer_stacklevel():
"""The ``stacklevel`` that attributes a warning to the importing code.
This module can be imported through ``dateutil.__getattr__`` (e.g. by
``from dateutil import zoneinfo``), which calls
``importlib.import_module``; the warnings machinery skips the import
system's own frames, but not those two, so skip them here.
"""
level = 1
frame = sys._getframe(1) # The body of this module
while frame.f_back is not None:
frame = frame.f_back
filename = frame.f_code.co_filename
if "importlib" in filename and "_bootstrap" in filename:
# Since Python 3.5, the warnings machinery skips these frames
# without counting them; before that they count like any other.
if sys.version_info < (3, 5):
level += 1
continue
level += 1
if frame.f_globals.get("__name__") not in ("importlib", "dateutil"):
return level
return 2
warnings.warn(
"The `dateutil.zoneinfo` module has been replaced with a wrapper around "
"the tzdata package, and its use is deprecated, to be removed in a future "
"version. Use the standard library module `zoneinfo` or `dateutil.tz` "
"instead.",
DeprecationWarning,
stacklevel=_importer_stacklevel(),
)
tzfile = _tzfile
class ZoneInfoFile(object):
def __init__(self, zonefile_stream=None):
if zonefile_stream is not None:
self._load_legacy_zonefile_stream(zonefile_stream)
else:
self._eager_load_tzdata()
def _eager_load_tzdata(self):
try:
import tzdata
except ImportError as e:
six.raise_from(
ImportError(
"The tzdata module is required to use ZoneInfoFile; either add "
"a dependency on tzdata or migrate away from dateutil.zoneinfo."
),
e,
)
zone_dict = {}
for key in _tzdata_impl._load_tzdata_keys():
with _tzdata_impl._load_tzdata(key) as f:
zone_dict[key] = tzfile(f, key=key)
self.zones = zone_dict
self.metadata = {
"metadata_version": "3.0",
"tzversion": tzdata.IANA_VERSION,
}
def _load_legacy_zonefile_stream(self, zonefile_stream):
with TarFile.open(fileobj=zonefile_stream) as tf:
self.zones = {
zf.name: tzfile(tf.extractfile(zf), filename=zf.name)
for zf in tf.getmembers()
if zf.isfile() and zf.name != METADATA_FN
}
# deal with links: They'll point to their parent object. Less
# waste of memory
links = {
zl.name: self.zones[zl.linkname]
for zl in tf.getmembers()
if zl.islnk() or zl.issym()
}
self.zones.update(links)
try:
metadata_json = tf.extractfile(tf.getmember(METADATA_FN))
metadata_str = metadata_json.read().decode("UTF-8")
self.metadata = json.loads(metadata_str)
except KeyError:
# no metadata in tar file
self.metadata = None
def get(self, name, default=None):
"""
Wrapper for :func:`ZoneInfoFile.zones.get`. This is a convenience method
for retrieving zones from the zone dictionary.
:param name:
The name of the zone to retrieve. (Generally IANA zone names)
:param default:
The value to return in the event of a missing key.
.. versionadded:: 2.6.0
"""
return self.zones.get(name, default)
# The current API has gettz as a module function, although in fact it taps into
# a stateful class. So as a workaround for now, without changing the API, we
# will create a new "global" class instance the first time a user requests a
# timezone. Ugly, but adheres to the api.
#
# TODO: Remove after deprecation period.
_CLASS_ZONE_INSTANCE = []
def get_zonefile_instance(new_instance=False):
"""
This is a convenience function which provides a :class:`ZoneInfoFile`
instance using the data provided by the ``dateutil`` package. By default, it
caches a single instance of the ZoneInfoFile object and returns that.
:param new_instance:
If ``True``, a new instance of :class:`ZoneInfoFile` is instantiated and
used as the cached instance for the next call. Otherwise, new instances
are created only as necessary.
:return:
Returns a :class:`ZoneInfoFile` object.
.. versionadded:: 2.6
"""
if new_instance:
zif = None
else:
zif = getattr(get_zonefile_instance, '_cached_instance', None)
if zif is None:
zif = ZoneInfoFile()
get_zonefile_instance._cached_instance = zif
return zif
def gettz(name):
"""
This retrieves a time zone from the ``tzdata`` package.
:param name:
An IANA-style time zone name, as found in the zoneinfo file.
:return:
Returns a :class:`dateutil.tz.tzfile` time zone object.
.. warning::
It is generally inadvisable to use this function, and it is only
provided for API compatibility with earlier versions. This is *not*
equivalent to ``dateutil.tz.gettz()``, which selects an appropriate
time zone based on the inputs, favoring system zoneinfo. This is ONLY
for accessing the dateutil-specific zoneinfo (which may be out of
date compared to the system zoneinfo).
.. deprecated:: 2.6
If you need to use a specific zoneinfofile over the system zoneinfo,
instantiate a :class:`dateutil.zoneinfo.ZoneInfoFile` object and call
:func:`dateutil.zoneinfo.ZoneInfoFile.get(name)` instead.
Use :func:`get_zonefile_instance` to retrieve an instance of the
dateutil-provided zoneinfo.
"""
warnings.warn("zoneinfo.gettz() will be removed in future versions, "
"to use the dateutil-provided zoneinfo files, instantiate a "
"ZoneInfoFile object and use ZoneInfoFile.zones.get() "
"instead. See the documentation for details.",
DeprecationWarning)
if len(_CLASS_ZONE_INSTANCE) == 0:
_CLASS_ZONE_INSTANCE.append(ZoneInfoFile())
return _CLASS_ZONE_INSTANCE[0].zones.get(name)
def gettz_db_metadata():
"""Get the zonefile metadata
:returns:
A dictionary with the database metadata
.. deprecated:: 2.6
See deprecation warning in :func:`zoneinfo.gettz`. To get metadata,
query the attribute ``zoneinfo.ZoneInfoFile.metadata``.
"""
warnings.warn("zoneinfo.gettz_db_metadata() will be removed in future "
"versions, to use the dateutil-provided zoneinfo files, "
"ZoneInfoFile object and query the 'metadata' attribute "
"instead. See the documentation for details.",
DeprecationWarning)
if len(_CLASS_ZONE_INSTANCE) == 0:
_CLASS_ZONE_INSTANCE.append(ZoneInfoFile())
return _CLASS_ZONE_INSTANCE[0].metadata