summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2021-10-31 21:15:37 +0100
committerAnthon van der Neut <anthon@mnt.org>2021-10-31 21:15:37 +0100
commit930a54b4685b5a259819d1f069c95b3bb674b681 (patch)
tree9665aa00883a4d9dd071bf0c7567c60fa7113400
parentbaf8bf17c714aca91083bfdeb734aa5b607d236c (diff)
downloadruamel.yaml-930a54b4685b5a259819d1f069c95b3bb674b681.tar.gz
extract timestamp matching/creation to util.py0.17.17
-rw-r--r--CHANGES3
-rw-r--r--README.rst11
-rw-r--r--__init__.py4
-rw-r--r--_doc/_static/pypi.svg2
-rw-r--r--comments.py15
-rw-r--r--constructor.py62
-rw-r--r--util.py58
7 files changed, 87 insertions, 68 deletions
diff --git a/CHANGES b/CHANGES
index 06e6680..4099578 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+[0, 17, 17]: 2021-10-31
+ - extract timestamp matching/creation to util
+
[0, 17, 16]: 2021-08-28
- also handle issue 397 when comment is newline
diff --git a/README.rst b/README.rst
index a9cd69e..0db06d2 100644
--- a/README.rst
+++ b/README.rst
@@ -4,13 +4,13 @@ ruamel.yaml
``ruamel.yaml`` is a YAML 1.2 loader/dumper package for Python.
-:version: 0.17.16
-:updated: 2021-08-28
+:version: 0.17.17
+:updated: 2021-10-31
:documentation: http://yaml.readthedocs.io
:repository: https://sourceforge.net/projects/ruamel-yaml/
:pypi: https://pypi.org/project/ruamel.yaml/
-*The 0.16.13 release was the last that will tested to be working on Python 2.7.
+*The 0.16.13 release was the last that was tested to be working on Python 2.7.
The 0.17 series will still be tested on Python 3.5, but the 0.18 will not. The
0.17 series will also stop support for the old PyYAML functions, so a `YAML()` instance
will need to be created.*
@@ -72,8 +72,11 @@ ChangeLog
.. should insert NEXT: at the beginning of line for next key (with empty line)
+0.17.17 (2021-10-31):
+ - extract timestamp matching/creation to util
+
0.17.16 (2021-08-28):
- - also handle issue 397 when comment is newline
+ - 398 also handle issue 397 when comment is newline
0.17.15 (2021-08-28):
- fix issue 397, insert comment before key when a comment between key and value exists
diff --git a/__init__.py b/__init__.py
index 53e8b51..5124d2c 100644
--- a/__init__.py
+++ b/__init__.py
@@ -5,8 +5,8 @@ if False: # MYPY
_package_data = dict(
full_package_name='ruamel.yaml',
- version_info=(0, 17, 16),
- __version__='0.17.16',
+ version_info=(0, 17, 17),
+ __version__='0.17.17',
author='Anthon van der Neut',
author_email='a.van.der.neut@ruamel.eu',
description='ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order', # NOQA
diff --git a/_doc/_static/pypi.svg b/_doc/_static/pypi.svg
index c59acf1..35042d8 100644
--- a/_doc/_static/pypi.svg
+++ b/_doc/_static/pypi.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="86" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#007ec6" d="M33 0h53v20H33z"/><path fill="url(#b)" d="M0 0h86v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="230">pypi</text><text x="175" y="140" transform="scale(.1)" textLength="230">pypi</text><text x="585" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">0.17.16</text><text x="585" y="140" transform="scale(.1)" textLength="430">0.17.16</text></g> </svg>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="86" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#007ec6" d="M33 0h53v20H33z"/><path fill="url(#b)" d="M0 0h86v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="230">pypi</text><text x="175" y="140" transform="scale(.1)" textLength="230">pypi</text><text x="585" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">0.17.17</text><text x="585" y="140" transform="scale(.1)" textLength="430">0.17.17</text></g> </svg>
diff --git a/comments.py b/comments.py
index 053b4f1..11ee8ad 100644
--- a/comments.py
+++ b/comments.py
@@ -870,12 +870,13 @@ class CommentedMap(ordereddict, CommentedBase):
# probably a dict that is used
for x in vals[0]:
self[x] = vals[0][x]
- try:
- self._ok.update(vals[0].keys()) # type: ignore
- except AttributeError:
- # assume one argument that is a list/tuple of two element lists/tuples
- for x in vals[0]:
- self._ok.add(x[0])
+ if vals:
+ try:
+ self._ok.update(vals[0].keys()) # type: ignore
+ except AttributeError:
+ # assume one argument that is a list/tuple of two element lists/tuples
+ for x in vals[0]:
+ self._ok.add(x[0])
if kw:
self._ok.add(*kw.keys())
@@ -980,7 +981,7 @@ class CommentedMap(ordereddict, CommentedBase):
# # not found in merged in stuff
# ordereddict.__delitem__(self, key)
# for referer in self._ref:
- # referer.update_key_value(key)
+ # referer.update=_key_value(key)
# return
#
# ordereddict.__setitem__(self, key, value) # merge might have different value
diff --git a/constructor.py b/constructor.py
index e608db4..bb4eb32 100644
--- a/constructor.py
+++ b/constructor.py
@@ -3,7 +3,6 @@
import datetime
import base64
import binascii
-import re
import sys
import types
import warnings
@@ -32,7 +31,7 @@ from ruamel.yaml.scalarint import ScalarInt, BinaryInt, OctalInt, HexInt, HexCap
from ruamel.yaml.scalarfloat import ScalarFloat
from ruamel.yaml.scalarbool import ScalarBoolean
from ruamel.yaml.timestamp import TimeStamp
-from ruamel.yaml.util import RegExp
+from ruamel.yaml.util import timestamp_regexp, create_timestamp
if False: # MYPY
from typing import Any, Dict, List, Set, Generator, Union, Optional # NOQA
@@ -554,19 +553,7 @@ class SafeConstructor(BaseConstructor):
node.start_mark,
)
- timestamp_regexp = RegExp(
- """^(?P<year>[0-9][0-9][0-9][0-9])
- -(?P<month>[0-9][0-9]?)
- -(?P<day>[0-9][0-9]?)
- (?:((?P<t>[Tt])|[ \\t]+) # explictly not retaining extra spaces
- (?P<hour>[0-9][0-9]?)
- :(?P<minute>[0-9][0-9])
- :(?P<second>[0-9][0-9])
- (?:\\.(?P<fraction>[0-9]*))?
- (?:[ \\t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
- (?::(?P<tz_minute>[0-9][0-9]))?))?)?$""",
- re.X,
- )
+ timestamp_regexp = timestamp_regexp # moved to util 0.17.17
def construct_yaml_timestamp(self, node, values=None):
# type: (Any, Any) -> Any
@@ -583,42 +570,7 @@ class SafeConstructor(BaseConstructor):
node.start_mark,
)
values = match.groupdict()
- year = int(values['year'])
- month = int(values['month'])
- day = int(values['day'])
- if not values['hour']:
- return datetime.date(year, month, day)
- hour = int(values['hour'])
- minute = int(values['minute'])
- second = int(values['second'])
- fraction = 0
- if values['fraction']:
- fraction_s = values['fraction'][:6]
- while len(fraction_s) < 6:
- fraction_s += '0'
- fraction = int(fraction_s)
- if len(values['fraction']) > 6 and int(values['fraction'][6]) > 4:
- fraction += 1
- delta = None
- if values['tz_sign']:
- tz_hour = int(values['tz_hour'])
- minutes = values['tz_minute']
- tz_minute = int(minutes) if minutes else 0
- delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute)
- if values['tz_sign'] == '-':
- delta = -delta
- # should do something else instead (or hook this up to the preceding if statement
- # in reverse
- # if delta is None:
- # return datetime.datetime(year, month, day, hour, minute, second, fraction)
- # return datetime.datetime(year, month, day, hour, minute, second, fraction,
- # datetime.timezone.utc)
- # the above is not good enough though, should provide tzinfo. In Python3 that is easily
- # doable drop that kind of support for Python2 as it has not native tzinfo
- data = datetime.datetime(year, month, day, hour, minute, second, fraction)
- if delta:
- data -= delta
- return data
+ return create_timestamp(**values)
def construct_yaml_omap(self, node):
# type: (Any) -> Any
@@ -1799,12 +1751,14 @@ class RoundTripConstructor(SafeConstructor):
)
values = match.groupdict()
if not values['hour']:
- return SafeConstructor.construct_yaml_timestamp(self, node, values)
+ return create_timestamp(**values)
+ # return SafeConstructor.construct_yaml_timestamp(self, node, values)
for part in ['t', 'tz_sign', 'tz_hour', 'tz_minute']:
if values[part]:
break
else:
- return SafeConstructor.construct_yaml_timestamp(self, node, values)
+ return create_timestamp(**values)
+ # return SafeConstructor.construct_yaml_timestamp(self, node, values)
year = int(values['year'])
month = int(values['month'])
day = int(values['day'])
@@ -1827,7 +1781,7 @@ class RoundTripConstructor(SafeConstructor):
delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute)
if values['tz_sign'] == '-':
delta = -delta
- # shold check for NOne and solve issue 366 should be tzinfo=delta)
+ # should check for None and solve issue 366 should be tzinfo=delta)
if delta:
dt = datetime.datetime(year, month, day, hour, minute)
dt -= delta
diff --git a/util.py b/util.py
index 8c7af47..c2ab46f 100644
--- a/util.py
+++ b/util.py
@@ -4,6 +4,7 @@
some helper functions that might be generally useful
"""
+import datetime
from functools import partial
import re
@@ -48,6 +49,63 @@ class LazyEval:
RegExp = partial(LazyEval, re.compile)
+timestamp_regexp = RegExp(
+ """^(?P<year>[0-9][0-9][0-9][0-9])
+ -(?P<month>[0-9][0-9]?)
+ -(?P<day>[0-9][0-9]?)
+ (?:((?P<t>[Tt])|[ \\t]+) # explictly not retaining extra spaces
+ (?P<hour>[0-9][0-9]?)
+ :(?P<minute>[0-9][0-9])
+ :(?P<second>[0-9][0-9])
+ (?:\\.(?P<fraction>[0-9]*))?
+ (?:[ \\t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
+ (?::(?P<tz_minute>[0-9][0-9]))?))?)?$""",
+ re.X,
+)
+
+
+def create_timestamp(
+ year, month, day, t, hour, minute, second, fraction, tz, tz_sign, tz_hour, tz_minute
+):
+ year = int(year)
+ month = int(month)
+ day = int(day)
+ if not hour:
+ return datetime.date(year, month, day)
+ hour = int(hour)
+ minute = int(minute)
+ second = int(second)
+ if fraction:
+ frac = 0
+ frac_s = fraction[:6]
+ while len(frac_s) < 6:
+ frac_s += '0'
+ frac = int(frac_s)
+ if len(fraction) > 6 and int(fraction[6]) > 4:
+ frac += 1
+ fraction = frac
+ else:
+ fraction = 0
+ delta = None
+ if tz_sign:
+ tz_hour = int(tz_hour)
+ tz_minute = int(tz_minute) if tz_minute else 0
+ delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute)
+ if tz_sign == '-':
+ delta = -delta
+ # should do something else instead (or hook this up to the preceding if statement
+ # in reverse
+ # if delta is None:
+ # return datetime.datetime(year, month, day, hour, minute, second, fraction)
+ # return datetime.datetime(year, month, day, hour, minute, second, fraction,
+ # datetime.timezone.utc)
+ # the above is not good enough though, should provide tzinfo. In Python3 that is easily
+ # doable drop that kind of support for Python2 as it has not native tzinfo
+ data = datetime.datetime(year, month, day, hour, minute, second, fraction)
+ if delta:
+ data -= delta
+ return data
+
# originally as comment
# https://github.com/pre-commit/pre-commit/pull/211#issuecomment-186466605