Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/dateutil/zoneinfo/__init__.py @ 0:d30785e31577 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author | guerler |
---|---|
date | Fri, 31 Jul 2020 00:18:57 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d30785e31577 |
---|---|
1 # -*- coding: utf-8 -*- | |
2 import warnings | |
3 import json | |
4 | |
5 from tarfile import TarFile | |
6 from pkgutil import get_data | |
7 from io import BytesIO | |
8 | |
9 from dateutil.tz import tzfile as _tzfile | |
10 | |
11 __all__ = ["get_zonefile_instance", "gettz", "gettz_db_metadata"] | |
12 | |
13 ZONEFILENAME = "dateutil-zoneinfo.tar.gz" | |
14 METADATA_FN = 'METADATA' | |
15 | |
16 | |
17 class tzfile(_tzfile): | |
18 def __reduce__(self): | |
19 return (gettz, (self._filename,)) | |
20 | |
21 | |
22 def getzoneinfofile_stream(): | |
23 try: | |
24 return BytesIO(get_data(__name__, ZONEFILENAME)) | |
25 except IOError as e: # TODO switch to FileNotFoundError? | |
26 warnings.warn("I/O error({0}): {1}".format(e.errno, e.strerror)) | |
27 return None | |
28 | |
29 | |
30 class ZoneInfoFile(object): | |
31 def __init__(self, zonefile_stream=None): | |
32 if zonefile_stream is not None: | |
33 with TarFile.open(fileobj=zonefile_stream) as tf: | |
34 self.zones = {zf.name: tzfile(tf.extractfile(zf), filename=zf.name) | |
35 for zf in tf.getmembers() | |
36 if zf.isfile() and zf.name != METADATA_FN} | |
37 # deal with links: They'll point to their parent object. Less | |
38 # waste of memory | |
39 links = {zl.name: self.zones[zl.linkname] | |
40 for zl in tf.getmembers() if | |
41 zl.islnk() or zl.issym()} | |
42 self.zones.update(links) | |
43 try: | |
44 metadata_json = tf.extractfile(tf.getmember(METADATA_FN)) | |
45 metadata_str = metadata_json.read().decode('UTF-8') | |
46 self.metadata = json.loads(metadata_str) | |
47 except KeyError: | |
48 # no metadata in tar file | |
49 self.metadata = None | |
50 else: | |
51 self.zones = {} | |
52 self.metadata = None | |
53 | |
54 def get(self, name, default=None): | |
55 """ | |
56 Wrapper for :func:`ZoneInfoFile.zones.get`. This is a convenience method | |
57 for retrieving zones from the zone dictionary. | |
58 | |
59 :param name: | |
60 The name of the zone to retrieve. (Generally IANA zone names) | |
61 | |
62 :param default: | |
63 The value to return in the event of a missing key. | |
64 | |
65 .. versionadded:: 2.6.0 | |
66 | |
67 """ | |
68 return self.zones.get(name, default) | |
69 | |
70 | |
71 # The current API has gettz as a module function, although in fact it taps into | |
72 # a stateful class. So as a workaround for now, without changing the API, we | |
73 # will create a new "global" class instance the first time a user requests a | |
74 # timezone. Ugly, but adheres to the api. | |
75 # | |
76 # TODO: Remove after deprecation period. | |
77 _CLASS_ZONE_INSTANCE = [] | |
78 | |
79 | |
80 def get_zonefile_instance(new_instance=False): | |
81 """ | |
82 This is a convenience function which provides a :class:`ZoneInfoFile` | |
83 instance using the data provided by the ``dateutil`` package. By default, it | |
84 caches a single instance of the ZoneInfoFile object and returns that. | |
85 | |
86 :param new_instance: | |
87 If ``True``, a new instance of :class:`ZoneInfoFile` is instantiated and | |
88 used as the cached instance for the next call. Otherwise, new instances | |
89 are created only as necessary. | |
90 | |
91 :return: | |
92 Returns a :class:`ZoneInfoFile` object. | |
93 | |
94 .. versionadded:: 2.6 | |
95 """ | |
96 if new_instance: | |
97 zif = None | |
98 else: | |
99 zif = getattr(get_zonefile_instance, '_cached_instance', None) | |
100 | |
101 if zif is None: | |
102 zif = ZoneInfoFile(getzoneinfofile_stream()) | |
103 | |
104 get_zonefile_instance._cached_instance = zif | |
105 | |
106 return zif | |
107 | |
108 | |
109 def gettz(name): | |
110 """ | |
111 This retrieves a time zone from the local zoneinfo tarball that is packaged | |
112 with dateutil. | |
113 | |
114 :param name: | |
115 An IANA-style time zone name, as found in the zoneinfo file. | |
116 | |
117 :return: | |
118 Returns a :class:`dateutil.tz.tzfile` time zone object. | |
119 | |
120 .. warning:: | |
121 It is generally inadvisable to use this function, and it is only | |
122 provided for API compatibility with earlier versions. This is *not* | |
123 equivalent to ``dateutil.tz.gettz()``, which selects an appropriate | |
124 time zone based on the inputs, favoring system zoneinfo. This is ONLY | |
125 for accessing the dateutil-specific zoneinfo (which may be out of | |
126 date compared to the system zoneinfo). | |
127 | |
128 .. deprecated:: 2.6 | |
129 If you need to use a specific zoneinfofile over the system zoneinfo, | |
130 instantiate a :class:`dateutil.zoneinfo.ZoneInfoFile` object and call | |
131 :func:`dateutil.zoneinfo.ZoneInfoFile.get(name)` instead. | |
132 | |
133 Use :func:`get_zonefile_instance` to retrieve an instance of the | |
134 dateutil-provided zoneinfo. | |
135 """ | |
136 warnings.warn("zoneinfo.gettz() will be removed in future versions, " | |
137 "to use the dateutil-provided zoneinfo files, instantiate a " | |
138 "ZoneInfoFile object and use ZoneInfoFile.zones.get() " | |
139 "instead. See the documentation for details.", | |
140 DeprecationWarning) | |
141 | |
142 if len(_CLASS_ZONE_INSTANCE) == 0: | |
143 _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream())) | |
144 return _CLASS_ZONE_INSTANCE[0].zones.get(name) | |
145 | |
146 | |
147 def gettz_db_metadata(): | |
148 """ Get the zonefile metadata | |
149 | |
150 See `zonefile_metadata`_ | |
151 | |
152 :returns: | |
153 A dictionary with the database metadata | |
154 | |
155 .. deprecated:: 2.6 | |
156 See deprecation warning in :func:`zoneinfo.gettz`. To get metadata, | |
157 query the attribute ``zoneinfo.ZoneInfoFile.metadata``. | |
158 """ | |
159 warnings.warn("zoneinfo.gettz_db_metadata() will be removed in future " | |
160 "versions, to use the dateutil-provided zoneinfo files, " | |
161 "ZoneInfoFile object and query the 'metadata' attribute " | |
162 "instead. See the documentation for details.", | |
163 DeprecationWarning) | |
164 | |
165 if len(_CLASS_ZONE_INSTANCE) == 0: | |
166 _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream())) | |
167 return _CLASS_ZONE_INSTANCE[0].metadata |