vortex-nwp 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vortex/__init__.py +159 -0
- vortex/algo/__init__.py +13 -0
- vortex/algo/components.py +2462 -0
- vortex/algo/mpitools.py +1953 -0
- vortex/algo/mpitools_templates/__init__.py +1 -0
- vortex/algo/mpitools_templates/envelope_wrapper_default.tpl +27 -0
- vortex/algo/mpitools_templates/envelope_wrapper_mpiauto.tpl +29 -0
- vortex/algo/mpitools_templates/wrapstd_wrapper_default.tpl +18 -0
- vortex/algo/serversynctools.py +171 -0
- vortex/config.py +112 -0
- vortex/data/__init__.py +19 -0
- vortex/data/abstractstores.py +1510 -0
- vortex/data/containers.py +835 -0
- vortex/data/contents.py +622 -0
- vortex/data/executables.py +275 -0
- vortex/data/flow.py +119 -0
- vortex/data/geometries.ini +2689 -0
- vortex/data/geometries.py +799 -0
- vortex/data/handlers.py +1230 -0
- vortex/data/outflow.py +67 -0
- vortex/data/providers.py +487 -0
- vortex/data/resources.py +207 -0
- vortex/data/stores.py +1390 -0
- vortex/data/sync_templates/__init__.py +0 -0
- vortex/gloves.py +309 -0
- vortex/layout/__init__.py +20 -0
- vortex/layout/contexts.py +577 -0
- vortex/layout/dataflow.py +1220 -0
- vortex/layout/monitor.py +969 -0
- vortex/nwp/__init__.py +14 -0
- vortex/nwp/algo/__init__.py +21 -0
- vortex/nwp/algo/assim.py +537 -0
- vortex/nwp/algo/clim.py +1086 -0
- vortex/nwp/algo/coupling.py +831 -0
- vortex/nwp/algo/eda.py +840 -0
- vortex/nwp/algo/eps.py +785 -0
- vortex/nwp/algo/forecasts.py +886 -0
- vortex/nwp/algo/fpserver.py +1303 -0
- vortex/nwp/algo/ifsnaming.py +463 -0
- vortex/nwp/algo/ifsroot.py +404 -0
- vortex/nwp/algo/monitoring.py +263 -0
- vortex/nwp/algo/mpitools.py +694 -0
- vortex/nwp/algo/odbtools.py +1258 -0
- vortex/nwp/algo/oopsroot.py +916 -0
- vortex/nwp/algo/oopstests.py +220 -0
- vortex/nwp/algo/request.py +660 -0
- vortex/nwp/algo/stdpost.py +1641 -0
- vortex/nwp/data/__init__.py +30 -0
- vortex/nwp/data/assim.py +380 -0
- vortex/nwp/data/boundaries.py +314 -0
- vortex/nwp/data/climfiles.py +521 -0
- vortex/nwp/data/configfiles.py +153 -0
- vortex/nwp/data/consts.py +954 -0
- vortex/nwp/data/ctpini.py +149 -0
- vortex/nwp/data/diagnostics.py +209 -0
- vortex/nwp/data/eda.py +147 -0
- vortex/nwp/data/eps.py +432 -0
- vortex/nwp/data/executables.py +1045 -0
- vortex/nwp/data/fields.py +111 -0
- vortex/nwp/data/gridfiles.py +380 -0
- vortex/nwp/data/logs.py +584 -0
- vortex/nwp/data/modelstates.py +363 -0
- vortex/nwp/data/monitoring.py +193 -0
- vortex/nwp/data/namelists.py +696 -0
- vortex/nwp/data/obs.py +840 -0
- vortex/nwp/data/oopsexec.py +74 -0
- vortex/nwp/data/providers.py +207 -0
- vortex/nwp/data/query.py +206 -0
- vortex/nwp/data/stores.py +160 -0
- vortex/nwp/data/surfex.py +337 -0
- vortex/nwp/syntax/__init__.py +9 -0
- vortex/nwp/syntax/stdattrs.py +437 -0
- vortex/nwp/tools/__init__.py +10 -0
- vortex/nwp/tools/addons.py +40 -0
- vortex/nwp/tools/agt.py +67 -0
- vortex/nwp/tools/bdap.py +59 -0
- vortex/nwp/tools/bdcp.py +41 -0
- vortex/nwp/tools/bdm.py +24 -0
- vortex/nwp/tools/bdmp.py +54 -0
- vortex/nwp/tools/conftools.py +1661 -0
- vortex/nwp/tools/drhook.py +66 -0
- vortex/nwp/tools/grib.py +294 -0
- vortex/nwp/tools/gribdiff.py +104 -0
- vortex/nwp/tools/ifstools.py +203 -0
- vortex/nwp/tools/igastuff.py +273 -0
- vortex/nwp/tools/mars.py +68 -0
- vortex/nwp/tools/odb.py +657 -0
- vortex/nwp/tools/partitioning.py +258 -0
- vortex/nwp/tools/satrad.py +71 -0
- vortex/nwp/util/__init__.py +6 -0
- vortex/nwp/util/async.py +212 -0
- vortex/nwp/util/beacon.py +40 -0
- vortex/nwp/util/diffpygram.py +447 -0
- vortex/nwp/util/ens.py +279 -0
- vortex/nwp/util/hooks.py +139 -0
- vortex/nwp/util/taskdeco.py +85 -0
- vortex/nwp/util/usepygram.py +697 -0
- vortex/nwp/util/usetnt.py +101 -0
- vortex/proxy.py +6 -0
- vortex/sessions.py +374 -0
- vortex/syntax/__init__.py +9 -0
- vortex/syntax/stdattrs.py +867 -0
- vortex/syntax/stddeco.py +185 -0
- vortex/toolbox.py +1117 -0
- vortex/tools/__init__.py +20 -0
- vortex/tools/actions.py +523 -0
- vortex/tools/addons.py +316 -0
- vortex/tools/arm.py +96 -0
- vortex/tools/compression.py +325 -0
- vortex/tools/date.py +27 -0
- vortex/tools/ddhpack.py +10 -0
- vortex/tools/delayedactions.py +782 -0
- vortex/tools/env.py +541 -0
- vortex/tools/folder.py +834 -0
- vortex/tools/grib.py +738 -0
- vortex/tools/lfi.py +953 -0
- vortex/tools/listings.py +423 -0
- vortex/tools/names.py +637 -0
- vortex/tools/net.py +2124 -0
- vortex/tools/odb.py +10 -0
- vortex/tools/parallelism.py +368 -0
- vortex/tools/prestaging.py +210 -0
- vortex/tools/rawfiles.py +10 -0
- vortex/tools/schedulers.py +480 -0
- vortex/tools/services.py +940 -0
- vortex/tools/storage.py +996 -0
- vortex/tools/surfex.py +61 -0
- vortex/tools/systems.py +3976 -0
- vortex/tools/targets.py +440 -0
- vortex/util/__init__.py +9 -0
- vortex/util/config.py +1122 -0
- vortex/util/empty.py +24 -0
- vortex/util/helpers.py +216 -0
- vortex/util/introspection.py +69 -0
- vortex/util/iosponge.py +80 -0
- vortex/util/roles.py +49 -0
- vortex/util/storefunctions.py +129 -0
- vortex/util/structs.py +26 -0
- vortex/util/worker.py +162 -0
- vortex_nwp-2.0.0.dist-info/METADATA +67 -0
- vortex_nwp-2.0.0.dist-info/RECORD +144 -0
- vortex_nwp-2.0.0.dist-info/WHEEL +5 -0
- vortex_nwp-2.0.0.dist-info/licenses/LICENSE +517 -0
- vortex_nwp-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Stream/File compression tools.
|
|
3
|
+
|
|
4
|
+
The user interface for such tools is the :class:`CompressionPipeline`.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from contextlib import contextmanager
|
|
8
|
+
import io
|
|
9
|
+
import functools
|
|
10
|
+
import operator
|
|
11
|
+
|
|
12
|
+
import footprints
|
|
13
|
+
from bronx.fancies import loggers
|
|
14
|
+
from vortex.util.iosponge import IoSponge
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
#: No automatic export
|
|
18
|
+
__all__ = []
|
|
19
|
+
|
|
20
|
+
logger = loggers.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class CompressionPipeline:
|
|
24
|
+
"""Main interface to data compression algorithms."""
|
|
25
|
+
|
|
26
|
+
def __init__(self, system, compression=""):
|
|
27
|
+
"""
|
|
28
|
+
:param System system: The system object that will be used to carry out
|
|
29
|
+
the task.
|
|
30
|
+
:param str compression: The description of the compression tools that
|
|
31
|
+
will be used in this compression pipeline.
|
|
32
|
+
(e.g. 'gzip' will just compress/uncompress using the gzip software,
|
|
33
|
+
'gzip|bzip2' will use the gzip software piped to the bzip2 software
|
|
34
|
+
(which is useless), 'gzip&complevel=5' will use the gzip software
|
|
35
|
+
with a compression factor of 5.)
|
|
36
|
+
|
|
37
|
+
:note: See the subclasses of :class:`CompressionUnit` for a description
|
|
38
|
+
of available compression tools (and their options).
|
|
39
|
+
"""
|
|
40
|
+
self._units = list()
|
|
41
|
+
self._sh = system
|
|
42
|
+
self.description_string = compression
|
|
43
|
+
for c in [c for c in compression.split("|") if c]:
|
|
44
|
+
c_raw = c.split("&")
|
|
45
|
+
ckind = c_raw.pop(0)
|
|
46
|
+
cargs = dict([arg.split("=", 1) for arg in c_raw])
|
|
47
|
+
self.add_compression_unit(ckind, **cargs)
|
|
48
|
+
|
|
49
|
+
def add_compression_unit(self, unit, **kwargs):
|
|
50
|
+
"""Add a new compression tool to the compression pipeline.
|
|
51
|
+
|
|
52
|
+
:param str unit: The kind of the compression tool (see :class:`CompressionUnit`
|
|
53
|
+
subclases
|
|
54
|
+
:param kwargs: Options that will be used during the compression tool
|
|
55
|
+
initialisation
|
|
56
|
+
"""
|
|
57
|
+
c_unit = footprints.proxy.compression_unit(kind=unit, **kwargs)
|
|
58
|
+
if c_unit is None:
|
|
59
|
+
raise ValueError(
|
|
60
|
+
"The {:s} compression unit could not be found.".format(unit)
|
|
61
|
+
)
|
|
62
|
+
self._units.append(c_unit)
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def units(self):
|
|
66
|
+
"""The list of compression tools forming the compression pipeline."""
|
|
67
|
+
return self._units
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def _rawftp_shell(self):
|
|
71
|
+
"""The name of the corresponding rawftp specialshell (if relevant)."""
|
|
72
|
+
if len(self.units) == 1:
|
|
73
|
+
return self.units[0].rawftp_shell(self._sh)
|
|
74
|
+
else:
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def suffix(self):
|
|
79
|
+
"""The suffix usualy associated with this compression pipeline."""
|
|
80
|
+
s = ".".join([s.suffix for s in self.units])
|
|
81
|
+
return "." + s if s else ""
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def compression_factor(self):
|
|
85
|
+
"""The minimal compression factor expected with such a compression pipeline."""
|
|
86
|
+
return functools.reduce(
|
|
87
|
+
operator.mul, [s.cfactor for s in self.units], 1.0
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
@staticmethod
|
|
91
|
+
def _inputstream_size(stream):
|
|
92
|
+
"""Find out the size of a seekable input stream."""
|
|
93
|
+
estimated_size = 0
|
|
94
|
+
try:
|
|
95
|
+
stream.seek(0, io.SEEK_END)
|
|
96
|
+
estimated_size = stream.tell()
|
|
97
|
+
stream.seek(0)
|
|
98
|
+
except AttributeError:
|
|
99
|
+
logger.warning("Could not rewind <source:%s>", str(stream))
|
|
100
|
+
except OSError:
|
|
101
|
+
logger.debug("Seek trouble <source:%s>", str(stream))
|
|
102
|
+
return estimated_size
|
|
103
|
+
|
|
104
|
+
@contextmanager
|
|
105
|
+
def _openstream(self, local, mode="rb"):
|
|
106
|
+
"""If *local* is not an opened file, open it..."""
|
|
107
|
+
if isinstance(local, str):
|
|
108
|
+
localfh = open(local, mode)
|
|
109
|
+
yield localfh
|
|
110
|
+
localfh.close()
|
|
111
|
+
elif isinstance(local, io.IOBase):
|
|
112
|
+
yield local
|
|
113
|
+
else:
|
|
114
|
+
raise ValueError("Unknown type for {!s}".format(local))
|
|
115
|
+
|
|
116
|
+
def _genericstream_close(self, processes):
|
|
117
|
+
"""Close a list of Popen objects (and look for the returncode)."""
|
|
118
|
+
for i, p in enumerate(processes):
|
|
119
|
+
if not self._sh.pclose(p):
|
|
120
|
+
logger.error(
|
|
121
|
+
"Abnormal return code for one of the processes (#%d)", i
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
@contextmanager
|
|
125
|
+
def compress2stream(self, local, iosponge=False):
|
|
126
|
+
"""Compress *local* into a pipe or an :class:`IoSponge` object.
|
|
127
|
+
|
|
128
|
+
*local* can be an opened file-like object or a filename.
|
|
129
|
+
|
|
130
|
+
This method creates a context manager. Example::
|
|
131
|
+
|
|
132
|
+
source='myfile'
|
|
133
|
+
cp = CompressionPipeline(systemobj, 'gzip')
|
|
134
|
+
ftp = systemobj.ftp('hendrix.meteo.fr')
|
|
135
|
+
with cp.compress2stream(source) as csource:
|
|
136
|
+
ftp.put(csource, 'remote_compressedfile')
|
|
137
|
+
|
|
138
|
+
When leaving the context, the gzip process that compresses the data will
|
|
139
|
+
be properly closed
|
|
140
|
+
"""
|
|
141
|
+
with self._openstream(local) as stream:
|
|
142
|
+
estimated_size = (
|
|
143
|
+
self._inputstream_size(stream) * self.compression_factor
|
|
144
|
+
)
|
|
145
|
+
processes = list()
|
|
146
|
+
lstream = stream
|
|
147
|
+
for unit in self.units:
|
|
148
|
+
p = unit.compress(self._sh, lstream)
|
|
149
|
+
lstream = p.stdout
|
|
150
|
+
processes.append(p)
|
|
151
|
+
if iosponge:
|
|
152
|
+
yield IoSponge(lstream, guessed_size=estimated_size)
|
|
153
|
+
else:
|
|
154
|
+
yield lstream
|
|
155
|
+
self._genericstream_close(processes)
|
|
156
|
+
|
|
157
|
+
def _xcopyfileobj(self, in_fh, out_fh):
|
|
158
|
+
try:
|
|
159
|
+
self._sh.copyfileobj(in_fh, out_fh)
|
|
160
|
+
except OSError:
|
|
161
|
+
return False
|
|
162
|
+
else:
|
|
163
|
+
return True
|
|
164
|
+
|
|
165
|
+
def compress2file(self, local, destination):
|
|
166
|
+
"""Compress *local* into a file (named *destination*)
|
|
167
|
+
|
|
168
|
+
*local* can be an opened file-like object or a filename.
|
|
169
|
+
*destination* is a filename.
|
|
170
|
+
"""
|
|
171
|
+
with open(destination, "wb") as fhout:
|
|
172
|
+
with self.compress2stream(local) as fhcompressed:
|
|
173
|
+
return self._xcopyfileobj(fhcompressed, fhout)
|
|
174
|
+
|
|
175
|
+
def compress2rawftp(self, local):
|
|
176
|
+
"""
|
|
177
|
+
Return the name of the rawftp's specialshell that can be used to
|
|
178
|
+
compress the *local* data. It might return None.
|
|
179
|
+
"""
|
|
180
|
+
return self._rawftp_shell
|
|
181
|
+
|
|
182
|
+
@contextmanager
|
|
183
|
+
def stream2uncompress(self, destination):
|
|
184
|
+
"""Uncompress piped data to *destination*.
|
|
185
|
+
|
|
186
|
+
*destination* can be an opened file-like object or a filename.
|
|
187
|
+
|
|
188
|
+
This method creates a context manager. Example::
|
|
189
|
+
|
|
190
|
+
destination='mydownloadedfile'
|
|
191
|
+
cp = CompressionPipeline(systemobj, 'gzip')
|
|
192
|
+
ftp = systemobj.ftp('hendrix.meteo.fr')
|
|
193
|
+
with cp.stream2uncompress(destination) as cdestination:
|
|
194
|
+
ftp.get('remote_compressedfile', cdestination)
|
|
195
|
+
|
|
196
|
+
When leaving the context, the gunzip process that uncompresses the data
|
|
197
|
+
will be properly closed.
|
|
198
|
+
"""
|
|
199
|
+
with self._openstream(destination, "wb") as dstream:
|
|
200
|
+
processes = list()
|
|
201
|
+
instream = True
|
|
202
|
+
nunits = len(self.units)
|
|
203
|
+
for i, unit in enumerate(reversed(self.units)):
|
|
204
|
+
outstream = dstream if i == nunits - 1 else True
|
|
205
|
+
p = unit.uncompress(self._sh, instream, outstream)
|
|
206
|
+
instream = p.stdout
|
|
207
|
+
processes.append(p)
|
|
208
|
+
yield processes[0].stdin
|
|
209
|
+
self._genericstream_close(processes)
|
|
210
|
+
|
|
211
|
+
def file2uncompress(self, local, destination):
|
|
212
|
+
"""Uncompress *local* into *destination*.
|
|
213
|
+
|
|
214
|
+
*local* is a filename.
|
|
215
|
+
*destination* can be an opened file-like object or a filename.
|
|
216
|
+
"""
|
|
217
|
+
with self.stream2uncompress(destination) as fhuncompressed:
|
|
218
|
+
with open(local, "rb") as fhcompressed:
|
|
219
|
+
return self._xcopyfileobj(fhcompressed, fhuncompressed)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class CompressionUnit(footprints.FootprintBase):
|
|
223
|
+
"""Defines compress/uncompress methods for a given compression tool."""
|
|
224
|
+
|
|
225
|
+
_abstract = True
|
|
226
|
+
_collector = ("compression_unit",)
|
|
227
|
+
_footprint = dict(
|
|
228
|
+
info="Abstract Compression Unit",
|
|
229
|
+
attr=dict(
|
|
230
|
+
kind=dict(
|
|
231
|
+
info="The name of the compression tool.",
|
|
232
|
+
),
|
|
233
|
+
suffix=dict(
|
|
234
|
+
info="The usual file extension for this compression tool.",
|
|
235
|
+
optional=True,
|
|
236
|
+
),
|
|
237
|
+
cfactor=dict(
|
|
238
|
+
info="The usual compression factor for this compression tool.",
|
|
239
|
+
type=float,
|
|
240
|
+
default=1.0,
|
|
241
|
+
optional=True,
|
|
242
|
+
),
|
|
243
|
+
),
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
def rawftp_shell(self, sh):
|
|
247
|
+
"""The rawftp's speciall shell that may carry out a comparable compression."""
|
|
248
|
+
return None
|
|
249
|
+
|
|
250
|
+
def _run_in_pipe(self, sh, cmd, stream, outstream=True):
|
|
251
|
+
"""Run *cmd* with the piped input *stream*."""
|
|
252
|
+
p = sh.popen(cmd, stdin=stream, stdout=outstream, bufsize=8192)
|
|
253
|
+
return p
|
|
254
|
+
|
|
255
|
+
def compress(self, sh, stream):
|
|
256
|
+
"""Compress the input *stream*. Returns a Popen object."""
|
|
257
|
+
raise NotImplementedError()
|
|
258
|
+
|
|
259
|
+
def uncompress(self, sh, stream, outstream=True):
|
|
260
|
+
"""Uncompress the input *stream*. Returns a Popen object."""
|
|
261
|
+
raise NotImplementedError()
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
class GzipCompressionUnit(CompressionUnit):
|
|
265
|
+
_footprint = dict(
|
|
266
|
+
info="Compress/Uncompress a stream using gzip",
|
|
267
|
+
attr=dict(
|
|
268
|
+
kind=dict(values=["gzip", "gz"]),
|
|
269
|
+
suffix=dict(
|
|
270
|
+
default="gz",
|
|
271
|
+
),
|
|
272
|
+
complevel=dict(
|
|
273
|
+
info="The gzip algorithm compression level (see 'man gzip')",
|
|
274
|
+
type=int,
|
|
275
|
+
values=range(1, 10),
|
|
276
|
+
default=6,
|
|
277
|
+
optional=True,
|
|
278
|
+
),
|
|
279
|
+
cfactor=dict(default=0.9),
|
|
280
|
+
),
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
def compress(self, sh, stream):
|
|
284
|
+
"""Compress the input *stream*. Returns a Popen object."""
|
|
285
|
+
return self._run_in_pipe(
|
|
286
|
+
sh, ["gzip", "--stdout", "-{!s}".format(self.complevel)], stream
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
def uncompress(self, sh, stream, outstream=True):
|
|
290
|
+
"""Uncompress the input *stream*. Returns a Popen object."""
|
|
291
|
+
return self._run_in_pipe(sh, ["gunzip", "--stdout"], stream, outstream)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class Bzip2CompressionUnit(CompressionUnit):
|
|
295
|
+
_footprint = dict(
|
|
296
|
+
info="Compress/Uncompress a stream using bzip2",
|
|
297
|
+
attr=dict(
|
|
298
|
+
kind=dict(values=["bzip2", "bz2"]),
|
|
299
|
+
suffix=dict(
|
|
300
|
+
default="bz2",
|
|
301
|
+
),
|
|
302
|
+
complevel=dict(
|
|
303
|
+
info="The bzip2 algorithm compression level (see 'man bzip2')",
|
|
304
|
+
type=int,
|
|
305
|
+
values=range(1, 10),
|
|
306
|
+
default=9,
|
|
307
|
+
optional=True,
|
|
308
|
+
),
|
|
309
|
+
cfactor=dict(
|
|
310
|
+
default=0.85,
|
|
311
|
+
),
|
|
312
|
+
),
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
def compress(self, sh, stream):
|
|
316
|
+
"""Compress the input *stream*. Returns a Popen object."""
|
|
317
|
+
return self._run_in_pipe(
|
|
318
|
+
sh, ["bzip2", "--stdout", "-{!s}".format(self.complevel)], stream
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
def uncompress(self, sh, stream, outstream=True):
|
|
322
|
+
"""Uncompress the input *stream*. Returns a Popen object."""
|
|
323
|
+
return self._run_in_pipe(
|
|
324
|
+
sh, ["bunzip2", "--stdout"], stream, outstream
|
|
325
|
+
)
|
vortex/tools/date.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Classes and functions form this module are dedicated to the manipulation of
|
|
3
|
+
date and time quantities.
|
|
4
|
+
|
|
5
|
+
It is kept for backward compatibility, however :mod:`bronx.stdtypes.date` should
|
|
6
|
+
be used now and on.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
from bronx.stdtypes import date as _b_date
|
|
12
|
+
|
|
13
|
+
_ALIASES = _b_date.local_date_functions.copy()
|
|
14
|
+
_ALIASES.update(
|
|
15
|
+
dict(
|
|
16
|
+
guess=_b_date.guess,
|
|
17
|
+
daterange=_b_date.daterange,
|
|
18
|
+
stamp=_b_date.stamp,
|
|
19
|
+
Period=_b_date.Period,
|
|
20
|
+
Date=_b_date.Date,
|
|
21
|
+
Time=_b_date.Time,
|
|
22
|
+
Month=_b_date.Month,
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
for n, obj in _ALIASES.items():
|
|
27
|
+
sys.modules[__name__].__dict__.update(_ALIASES)
|