Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-parse for openSUSE:Factory checked in at 2026-02-23 16:12:50 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-parse (Old) and /work/SRC/openSUSE:Factory/.python-parse.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-parse" Mon Feb 23 16:12:50 2026 rev:15 rq:1334419 version:1.21.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-parse/python-parse.changes 2024-10-25 19:22:53.470756499 +0200 +++ /work/SRC/openSUSE:Factory/.python-parse.new.1977/python-parse.changes 2026-02-23 16:14:45.902814971 +0100 @@ -1,0 +2,10 @@ +Mon Feb 23 09:09:45 UTC 2026 - Dirk Müller <[email protected]> + +- update to 1.21.1: + * Fix microsecond precision loss in timestamp parsing +- update to 1.21.0: + * allow triggering CI manually + * Actually raise exception + * readme: Clarify 'd' type + +------------------------------------------------------------------- Old: ---- parse-1.20.2.tar.gz New: ---- parse-1.21.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-parse.spec ++++++ --- /var/tmp/diff_new_pack.DceXol/_old 2026-02-23 16:14:46.390835092 +0100 +++ /var/tmp/diff_new_pack.DceXol/_new 2026-02-23 16:14:46.390835092 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-parse # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -15,9 +15,10 @@ # Please submit bugfixes or comments via https://bugs.opensuse.org/ # + %{?sle15_python_module_pythons} Name: python-parse -Version: 1.20.2 +Version: 1.21.1 Release: 0 Summary: Python module for parsing strings using a "format" syntax License: MIT ++++++ parse-1.20.2.tar.gz -> parse-1.21.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parse-1.20.2/PKG-INFO new/parse-1.21.1/PKG-INFO --- old/parse-1.20.2/PKG-INFO 2024-06-11 06:41:48.747942400 +0200 +++ new/parse-1.21.1/PKG-INFO 2026-02-19 03:19:13.236063700 +0100 @@ -1,38 +1,19 @@ -Metadata-Version: 2.1 +Metadata-Version: 2.4 Name: parse -Version: 1.20.2 +Version: 1.21.1 Summary: parse() is the opposite of format() Author-email: Richard Jones <[email protected]> -Maintainer-email: Wim Glenn <[email protected]> -License: Copyright (c) 2012-2019 Richard Jones <[email protected]> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - +Maintainer-email: Wim Jeantine-Glenn <[email protected]> +License-Expression: MIT Project-URL: homepage, https://github.com/r1chardj0n3s/parse Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Software Development :: Code Generators Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: License :: OSI Approved :: MIT License Description-Content-Type: text/x-rst License-File: LICENSE +Dynamic: license-file Installation ------------ @@ -170,7 +151,8 @@ to seek the holy grail! If the text you're matching has braces in it you can match those by including -a double-brace ``{{`` or ``}}`` in your format string, just like format() does. +a double-brace ``{{`` or ``}}`` in your format string, the same escaping method +used in the ``format()`` syntax. Format Specification @@ -181,7 +163,7 @@ Most of `format()`'s `Format Specification Mini-Language`_ is supported: - [[fill]align][sign][0][width][.precision][type] + [[fill]align][sign][0][width][grouping][.precision][type] The differences between `parse()` and `format()` are: @@ -211,7 +193,7 @@ W Not letters, numbers and underscore str s Whitespace str S Non-whitespace str -d Digits (effectively integer numbers) int +d Integer numbers (optional sign, digits) int D Non-digit str n Numbers with thousands separators (, or .) int % Percentage (converted to value/100.0) float @@ -477,6 +459,8 @@ Changelog --------- +- 1.21.1 Fix microsecond precision loss in timestamp parsing (thanks @karthiksai109) +- 1.21.0 Allow grouping char (,_) in decimal format string (thanks @moi90) - 1.20.2 Template field names can now contain - character i.e. HYPHEN-MINUS, chr(0x2d) - 1.20.1 The `%f` directive accepts 1-6 digits, like strptime (thanks @bbertincourt) - 1.20.0 Added support for strptime codes (thanks @bendichter) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parse-1.20.2/README.rst new/parse-1.21.1/README.rst --- old/parse-1.20.2/README.rst 2024-06-11 06:40:54.000000000 +0200 +++ new/parse-1.21.1/README.rst 2026-02-19 03:16:54.000000000 +0100 @@ -134,7 +134,8 @@ to seek the holy grail! If the text you're matching has braces in it you can match those by including -a double-brace ``{{`` or ``}}`` in your format string, just like format() does. +a double-brace ``{{`` or ``}}`` in your format string, the same escaping method +used in the ``format()`` syntax. Format Specification @@ -145,7 +146,7 @@ Most of `format()`'s `Format Specification Mini-Language`_ is supported: - [[fill]align][sign][0][width][.precision][type] + [[fill]align][sign][0][width][grouping][.precision][type] The differences between `parse()` and `format()` are: @@ -175,7 +176,7 @@ W Not letters, numbers and underscore str s Whitespace str S Non-whitespace str -d Digits (effectively integer numbers) int +d Integer numbers (optional sign, digits) int D Non-digit str n Numbers with thousands separators (, or .) int % Percentage (converted to value/100.0) float @@ -441,6 +442,8 @@ Changelog --------- +- 1.21.1 Fix microsecond precision loss in timestamp parsing (thanks @karthiksai109) +- 1.21.0 Allow grouping char (,_) in decimal format string (thanks @moi90) - 1.20.2 Template field names can now contain - character i.e. HYPHEN-MINUS, chr(0x2d) - 1.20.1 The `%f` directive accepts 1-6 digits, like strptime (thanks @bbertincourt) - 1.20.0 Added support for strptime codes (thanks @bendichter) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parse-1.20.2/parse.egg-info/PKG-INFO new/parse-1.21.1/parse.egg-info/PKG-INFO --- old/parse-1.20.2/parse.egg-info/PKG-INFO 2024-06-11 06:41:48.000000000 +0200 +++ new/parse-1.21.1/parse.egg-info/PKG-INFO 2026-02-19 03:19:13.000000000 +0100 @@ -1,38 +1,19 @@ -Metadata-Version: 2.1 +Metadata-Version: 2.4 Name: parse -Version: 1.20.2 +Version: 1.21.1 Summary: parse() is the opposite of format() Author-email: Richard Jones <[email protected]> -Maintainer-email: Wim Glenn <[email protected]> -License: Copyright (c) 2012-2019 Richard Jones <[email protected]> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - +Maintainer-email: Wim Jeantine-Glenn <[email protected]> +License-Expression: MIT Project-URL: homepage, https://github.com/r1chardj0n3s/parse Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Software Development :: Code Generators Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: License :: OSI Approved :: MIT License Description-Content-Type: text/x-rst License-File: LICENSE +Dynamic: license-file Installation ------------ @@ -170,7 +151,8 @@ to seek the holy grail! If the text you're matching has braces in it you can match those by including -a double-brace ``{{`` or ``}}`` in your format string, just like format() does. +a double-brace ``{{`` or ``}}`` in your format string, the same escaping method +used in the ``format()`` syntax. Format Specification @@ -181,7 +163,7 @@ Most of `format()`'s `Format Specification Mini-Language`_ is supported: - [[fill]align][sign][0][width][.precision][type] + [[fill]align][sign][0][width][grouping][.precision][type] The differences between `parse()` and `format()` are: @@ -211,7 +193,7 @@ W Not letters, numbers and underscore str s Whitespace str S Non-whitespace str -d Digits (effectively integer numbers) int +d Integer numbers (optional sign, digits) int D Non-digit str n Numbers with thousands separators (, or .) int % Percentage (converted to value/100.0) float @@ -477,6 +459,8 @@ Changelog --------- +- 1.21.1 Fix microsecond precision loss in timestamp parsing (thanks @karthiksai109) +- 1.21.0 Allow grouping char (,_) in decimal format string (thanks @moi90) - 1.20.2 Template field names can now contain - character i.e. HYPHEN-MINUS, chr(0x2d) - 1.20.1 The `%f` directive accepts 1-6 digits, like strptime (thanks @bbertincourt) - 1.20.0 Added support for strptime codes (thanks @bendichter) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parse-1.20.2/parse.py new/parse-1.21.1/parse.py --- old/parse-1.20.2/parse.py 2024-06-11 06:40:54.000000000 +0200 +++ new/parse-1.21.1/parse.py 2026-02-19 03:16:19.000000000 +0100 @@ -11,7 +11,7 @@ from functools import partial -__version__ = "1.20.2" +__version__ = "1.21.1" __all__ = ["parse", "search", "findall", "with_pattern"] log = logging.getLogger(__name__) @@ -219,7 +219,7 @@ H, M, S = t if "." in S: S, u = S.split(".") - u = int(float("." + u) * 1000000) + u = int(u.ljust(6, "0")[:6]) S = int(S) H = int(H) M = int(M) @@ -288,7 +288,7 @@ elif is_time: return dt.time() else: - ValueError("Datetime not a date nor a time?") + raise ValueError("Datetime not a date nor a time?") # ref: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes @@ -349,7 +349,7 @@ def extract_format(format, extra_types): - """Pull apart the format [[fill]align][sign][0][width][.precision][type]""" + """Pull apart the format [[fill]align][sign][0][width][grouping][.precision][type]""" fill = align = None if format[0] in "<>=^": align = format[0] @@ -374,6 +374,14 @@ width += format[0] format = format[1:] + # Extract grouping option + if format.startswith(","): + format = format[1:] + grouping = "," + elif format.startswith("_"): + format = format[1:] + grouping = "_" + if format.startswith("."): # Precision isn't needed but we need to capture it so that # the ValueError isn't raised. @@ -736,8 +744,9 @@ width = r"{1,%s}" % int(format["width"]) else: width = "+" - s = r"\d{w}|[-+ ]?0[xX][0-9a-fA-F]{w}|[-+ ]?0[bB][01]{w}|[-+ ]?0[oO][0-7]{w}".format( - w=width + s = r"[-+ ]?[0-9{g}]{w}|[-+ ]?0[xX][0-9a-fA-F{g}]{w}|[-+ ]?0[bB][01{g}]{w}|[-+ ]?0[oO][0-7{g}]{w}".format( + w=width, + g=format.get("grouping", ""), ) conv[group] = int_convert() # do not specify number base, determine it automatically diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parse-1.20.2/pyproject.toml new/parse-1.21.1/pyproject.toml --- old/parse-1.20.2/pyproject.toml 2023-12-15 04:50:45.000000000 +0100 +++ new/parse-1.21.1/pyproject.toml 2026-02-19 03:16:19.000000000 +0100 @@ -7,14 +7,13 @@ dynamic = ["version"] readme = "README.rst" description = "parse() is the opposite of format()" -license = {file = "LICENSE"} +license = "MIT" classifiers = [ "Environment :: Web Environment", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "Topic :: Software Development :: Code Generators", "Topic :: Software Development :: Libraries :: Python Modules", - "License :: OSI Approved :: MIT License", ] [[project.authors]] @@ -22,7 +21,7 @@ email = "[email protected]" [[project.maintainers]] -name = "Wim Glenn" +name = "Wim Jeantine-Glenn" email = "[email protected]" [project.urls] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parse-1.20.2/tests/test_bugs.py new/parse-1.21.1/tests/test_bugs.py --- old/parse-1.20.2/tests/test_bugs.py 2023-11-25 03:56:59.000000000 +0100 +++ new/parse-1.21.1/tests/test_bugs.py 2026-02-19 03:15:00.000000000 +0100 @@ -101,3 +101,21 @@ def test_match_trailing_newline(): r = parse.parse("{}", "test\n") assert r[0] == "test\n" + + +def test_microsecond_precision_issue162(): + # fractional seconds that previously suffered floating-point rounding + r = parse.parse("{:ti}", "2023-10-14T15:09:08.501902Z") + assert r[0].microsecond == 501902 + + # fewer than 6 fractional digits should be zero-padded + r = parse.parse("{:ti}", "2023-10-14T15:09:08.1Z") + assert r[0].microsecond == 100000 + + # exactly 6 fractional digits + r = parse.parse("{:ti}", "2023-10-14T15:09:08.123456Z") + assert r[0].microsecond == 123456 + + # more than 6 fractional digits should be truncated + r = parse.parse("{:ti}", "2023-10-14T15:09:08.1234567Z") + assert r[0].microsecond == 123456 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parse-1.20.2/tests/test_parse.py new/parse-1.21.1/tests/test_parse.py --- old/parse-1.20.2/tests/test_parse.py 2024-06-11 06:40:54.000000000 +0200 +++ new/parse-1.21.1/tests/test_parse.py 2026-02-05 19:18:50.000000000 +0100 @@ -235,7 +235,7 @@ def y(fmt, s, e, str_equals=False): p = parse.compile(fmt) r = p.parse(s) - assert r is not None + assert r is not None, "{!r} does not match {!r} ({!r})".format(s, fmt, p._expression) r = r.fixed[0] if str_equals: assert str(r) == str(e) @@ -338,6 +338,14 @@ y("a {:b} b", "a +1010 b", 10) y("a {:x} b", "a +1010 b", 0x1010) + # Test that grouping is handled correctly + y("a {:,d} b", "a 1,000,000 b", 1000000, str_equals=True) + y("a {:,d} b", "a -1,000,000 b", -1000000, str_equals=True) + + # Py 3.6+ (https://peps.python.org/pep-0515/) + y("a {:_d} b", "a 1_000_000 b", 1000000, str_equals=True) + y("a {:_d} b", "a -1_000_000 b", -1000000, str_equals=True) + def test_two_datetimes(): r = parse.parse("a {:ti} {:ti} b", "a 1997-07-16 2012-08-01 b")
