Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pyaml for openSUSE:Factory 
checked in at 2026-03-09 16:11:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pyaml (Old)
 and      /work/SRC/openSUSE:Factory/.python-pyaml.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pyaml"

Mon Mar  9 16:11:40 2026 rev:17 rq:1337530 version:26.2.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pyaml/python-pyaml.changes        
2025-07-14 10:58:09.584693245 +0200
+++ /work/SRC/openSUSE:Factory/.python-pyaml.new.8177/python-pyaml.changes      
2026-03-09 16:12:20.767416907 +0100
@@ -1,0 +2,7 @@
+Sun Mar  8 21:08:28 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 26.2.1:
+  * cli: add -o/--out-file option
+  * cli: allow reading/replacing multiple input files
+
+-------------------------------------------------------------------

Old:
----
  pyaml-25.7.0.tar.gz

New:
----
  pyaml-26.2.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pyaml.spec ++++++
--- /var/tmp/diff_new_pack.UMpksY/_old  2026-03-09 16:12:23.311521669 +0100
+++ /var/tmp/diff_new_pack.UMpksY/_new  2026-03-09 16:12:23.311521669 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-pyaml
 #
-# Copyright (c) 2025 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
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-pyaml
-Version:        25.7.0
+Version:        26.2.1
 Release:        0
 Summary:        Python module to produce formatted YAML-serialized data
 License:        WTFPL

++++++ pyaml-25.7.0.tar.gz -> pyaml-26.2.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyaml-25.7.0/PKG-INFO new/pyaml-26.2.1/PKG-INFO
--- old/pyaml-25.7.0/PKG-INFO   2025-07-10 20:44:48.431457000 +0200
+++ new/pyaml-26.2.1/PKG-INFO   2026-02-06 14:49:27.148404400 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: pyaml
-Version: 25.7.0
+Version: 26.2.1
 Summary: PyYAML-based module to produce a bit more pretty and readable 
YAML-serialized data
 Home-page: https://github.com/mk-fg/pretty-yaml
 Author: Mike Kazantsev
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyaml-25.7.0/pyaml/__init__.py 
new/pyaml-26.2.1/pyaml/__init__.py
--- old/pyaml-25.7.0/pyaml/__init__.py  2025-06-19 22:37:36.000000000 +0200
+++ new/pyaml-26.2.1/pyaml/__init__.py  2026-01-28 08:28:15.000000000 +0100
@@ -53,9 +53,9 @@
                                        self.anchor_node(key)
                                        self.anchor_node(value, 
hints=hints+[key])
 
-       def serialize_node(self, node, parent, index):
-               if self.pyaml_force_embed: self.anchors[node] = 
self.serialized_nodes.clear()
-               return super().serialize_node(node, parent, index)
+       def ignore_aliases(self, data):
+               if self.pyaml_force_embed: return True
+               return super().ignore_aliases(data)
 
        def expect_block_sequence(self):
                self.increase_indent(flow=False, indentless=False)
@@ -76,7 +76,7 @@
                if self.analysis: self.analysis.allow_flow_plain = False
                return res
 
-       def choose_scalar_style(self, _re1=re.compile(r':(\s|$)')):
+       def choose_scalar_style(self, _re1=re.compile(r':(\s|\Z)')):
                if self.states[-1] == self.expect_block_mapping_simple_value:
                        # Mapping keys - disable overriding string style, strip 
comments
                        if self.pyaml_string_val_style: self.event.style = 
'plain'
@@ -140,7 +140,7 @@
                if self.pyaml_repr_unknown: # repr value as a short oneliner
                        if isinstance(n := self.pyaml_repr_unknown, bool): n = 
50
                        if len(s := repr(data).replace('\n', '⏎')) > n + 10:
-                               if (m := re.search(r' at (0x[0-9a-f]+>)$', s)) 
and n > len(m[0]):
+                               if (m := re.search(r' at (0x[0-9a-f]+>)\Z', s)) 
and n > len(m[0]):
                                        s = s[:n-len(m[0])] + f' 
~[{n:,d}/{len(s):,d}]~ ' + m[1]
                                else: s = s[:n] + f' ...[{n:,d}/{len(s):,d}]'
                        cls, node = data.__class__, self.represent_data(s)
@@ -201,7 +201,7 @@
                                        blocks.append((a, n, 
_add_vspacing(block)[a_seq:]))
                                ind_re_sub = None
                        if ind_re.match(line): item_lines.append(n)
-                       if m := re.match(r'( *)(- )?\S.*:(\s|$)', line):
+                       if m := re.match(r'( *)(- )?\S.*:(\s|\Z)', line):
                                a, a_seq, ind_re_sub = n+1, bool(m[2]), 
re.compile(m[1] + ' ')
                if ( split_items := len(lines) > split_lines and
                                len(item_lines) > split_count and 
(oneline_split or has_sub) ):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyaml-25.7.0/pyaml/cli.py 
new/pyaml-26.2.1/pyaml/cli.py
--- old/pyaml-25.7.0/pyaml/cli.py       2024-07-18 15:00:40.000000000 +0200
+++ new/pyaml-26.2.1/pyaml/cli.py       2026-02-06 14:34:30.000000000 +0100
@@ -5,7 +5,7 @@
 @contextlib.contextmanager
 def safe_replacement(path, *open_args, mode=None, xattrs=None, **open_kws):
        'Context to atomically create/replace file-path in-place unless errors 
are raised'
-       path, xattrs = str(path), None
+       path = str(path)
        if mode is None:
                try: mode = stat.S_IMODE(os.lstat(path).st_mode)
                except FileNotFoundError: pass
@@ -54,10 +54,13 @@
        parser = argparse.ArgumentParser(
                formatter_class=argparse.RawTextHelpFormatter,
                description='Process and dump prettified YAML to stdout.')
-       parser.add_argument('path', nargs='?', metavar='path',
-               help='Path to YAML to read (default: use stdin).')
+       parser.add_argument('path', nargs='*', metavar='path', default=list(), 
help=dd('''
+               Path(s) to YAML to read (default/empty: use stdin).
+               With multiple paths, will output YAML documents from each one 
in the same order.'''))
        parser.add_argument('-r', '--replace', action='store_true',
-               help='Replace specified path with prettified version in-place.')
+               help='Replace specified YAML file(s) with prettified version 
in-place.')
+       parser.add_argument('-o', '--out-file', metavar='file-path',
+               help='Write output to specified file instead of standard 
output.')
        parser.add_argument('-w', '--width', type=int, metavar='chars', 
help=dd('''
                Max line width hint to pass to pyyaml for the dump.
                Only used to format scalars and collections (e.g. lists).'''))
@@ -80,15 +83,6 @@
                help='Disable sanity-check on the output and suppress stderr 
warnings.')
        opts = parser.parse_args(sys.argv[1:] if argv is None else argv)
 
-       if opts.replace and not opts.path:
-               parser.error('-r/--replace option can only be used with a file 
path, not stdin')
-
-       src = open(opts.path) if opts.path else stdin
-       try:
-               data = list( yaml.safe_load_all(src) if not opts.lines else
-                       (yaml.safe_load(chunk) for chunk in file_line_iter(src) 
if chunk.strip()) )
-       finally: src.close()
-
        pyaml_kwargs = dict()
        if opts.width: pyaml_kwargs['width'] = opts.width
        if vspacing := opts.vspacing:
@@ -104,24 +98,41 @@
                        if count: vspacing['split_count'] = int(count.strip())
                if vspacing: pyaml_kwargs['vspacing'] = vspacing
 
-       if len(data) > 1: ys = pyaml.dump_all(data, **pyaml_kwargs)
-       else: ys = pyaml.dump(data[0], **pyaml_kwargs) # avoids leading "---"
+       if not all(paths := opts.path or ['']) and opts.replace:
+               parser.error('-r/--replace option can only be used with a file 
path, not stdin')
+       if opts.out_file and opts.replace:
+               parser.error('-r/--replace and -o/--out-file options cannot be 
used at the same time')
+       with contextlib.ExitStack() as srcs:
+               data = list([p, srcs.enter_context(open(p)) if p else stdin] 
for p in (paths or ['']))
+               for d in data: d[1] = list( yaml.safe_load_all(d[1]) if not 
opts.lines else
+                       (yaml.safe_load(chunk) for chunk in 
file_line_iter(d[1]) if chunk.strip()) )
+       for d in data: d.append(
+               pyaml.dump(d[1][0], **pyaml_kwargs) # avoid leading "---" if 
possible
+               if len(data) == len(d[1]) == 1 else pyaml.dump_all(d[1], 
**pyaml_kwargs) )
 
        if not opts.quiet:
                try:
-                       data_chk = list(yaml.safe_load_all(ys))
-                       try: data_hash = json.dumps(data, sort_keys=True)
-                       except: pass # too complex for checking with json
-                       else:
-                               if json.dumps(data_chk, sort_keys=True) != 
data_hash:
-                                       raise AssertionError('Data from 
before/after pyaml does not match')
+                       for p, d, ys in data:
+                               data_chk = list(yaml.safe_load_all(ys))
+                               try: data_hash = json.dumps(d, sort_keys=True)
+                               except: pass # too complex for checking with 
json
+                               else:
+                                       if json.dumps(data_chk, sort_keys=True) 
!= data_hash:
+                                               raise AssertionError('Data from 
before/after pyaml does not match')
                except Exception as err:
                        p_err = lambda *a,**kw: print(*a, **kw, file=stderr, 
flush=True)
-                       p_err( 'WARNING: Failed to parse produced YAML'
-                               ' output back to data, it is likely too 
complicated for pyaml' )
+                       p_err( 'WARNING: Failed to parse produced YAML output 
for'
+                               f' <{p or "stdin"}> back to same data, it is 
likely too complicated for pyaml' )
                        err = f'[{err.__class__.__name__}] {err}'
                        p_err('  raised error: ' + ' // '.join(map(str.strip, 
err.split('\n'))))
 
-       if opts.replace:
-               with safe_replacement(opts.path) as tmp: tmp.write(ys)
-       else: stdout.write(ys)
+       with contextlib.ExitStack() as dsts:
+               if opts.replace:
+                       for d in data: d[0] = 
dsts.enter_context(safe_replacement(d[0]))
+               elif p := opts.out_file:
+                       dst = dsts.enter_context( safe_replacement(p) if not
+                               any(p.startswith(pre) for pre in ['/dev/', 
'/proc/']) else open(p, 'w') )
+                       for d in data: d[0] = dst
+               else:
+                       for d in data: d[0] = stdout
+               for dst, d, ys in data: dst.write(ys)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyaml-25.7.0/pyaml/tests/test_cli.py 
new/pyaml-26.2.1/pyaml/tests/test_cli.py
--- old/pyaml-25.7.0/pyaml/tests/test_cli.py    2024-07-18 15:00:40.000000000 
+0200
+++ new/pyaml-26.2.1/pyaml/tests/test_cli.py    2026-02-06 14:47:05.000000000 
+0100
@@ -134,7 +134,7 @@
                err.seek(0); err.truncate()
 
                with tempfile.NamedTemporaryFile(prefix='.pyaml.test.') as tmp:
-                       d_json, d_yaml = json.dumps(d).encode(), pyaml.dump(d, 
bytes)
+                       d_json = json.dumps(d).encode()
                        tmp.write(d_json); tmp.flush()
                        os.fchmod(tmp.fileno(), 0o1510)
                        stat_tmp = os.fstat(tmp.fileno())
@@ -228,4 +228,69 @@
                self.assertNotIn('doc2_val', xd3)
                self.assertNotIn('---', out.getvalue())
 
+       def test_multiple_args(self):
+               ds, out, err = [data.copy(), dict(data, diff=123)], 
io.StringIO(), io.StringIO()
+               with tempfile.NamedTemporaryFile(prefix='.pyaml.test.') as 
tmp1, \
+                               
tempfile.NamedTemporaryFile(prefix='.pyaml.test.') as tmp2:
+                       tmp_files, ds_json = [tmp1, tmp2], 
list(json.dumps(d).encode() for d in ds)
+                       for tmp, d_json in zip(tmp_files, ds_json): 
tmp.write(d_json); tmp.flush()
+
+                       with self.assertRaises(SystemExit):
+                               sys.stdout, sys.stderr, sys_out, sys_err = out, 
err, sys.stdout, sys.stderr
+                               try: pyaml.cli.main(
+                                       argv=['-r', tmp1.name, '', tmp2.name], 
# empty arg = stdin
+                                       stdin=io.StringIO(), stdout=out, 
stderr=err )
+                               finally: sys.stdout, sys.stderr = sys_out, 
sys_err
+                               for tmp, d_json in zip(tmp_files, ds_json):
+                                       tmp.seek(0); 
self.assertEqual(tmp.read().decode(), d_json)
+                       self.assertEqual(out.getvalue(), '')
+                       self.assertGreater(len(err.getvalue()), 50)
+                       err.seek(0); err.truncate()
+
+                       pyaml.cli.main( argv=['-r', tmp1.name, tmp2.name],
+                               stdin=io.StringIO(), stdout=out, stderr=err )
+                       for tmp, d, d_json in zip(tmp_files, ds, ds_json):
+                               tmp.seek(0); d_yaml = tmp.read().decode()
+                               self.assertNotEqual(d_json, d_yaml)
+                               self.assertEqual(self.data_hash(d), 
self.data_hash(yaml.safe_load(d_yaml)))
+                       self.assertEqual(out.getvalue(), '')
+                       self.assertEqual(err.getvalue(), '')
+
+                       ys_stdin = yaml.safe_dump_all(
+                               d_stdin := [dict(ds[0], diff2=dict(a=['xyz'])), 
'abcde', [1,2,3]] )
+                       pyaml.cli.main( argv=[tmp2.name, '', tmp1.name],
+                               stdin=io.StringIO(ys_stdin), stdout=out, 
stderr=err )
+                       
self.assertEqual(list(yaml.safe_load_all(out.getvalue())), [ds[1], *d_stdin, 
ds[0]])
+
+       def test_out_file(self):
+               d, out, err = data.copy(), io.StringIO(), io.StringIO()
+               ys, ys_pyaml = yaml.safe_dump(d), pyaml.dump(d)
+               with tempfile.NamedTemporaryFile(prefix='.pyaml.test.') as tmp:
+                       tmp.write(d_tmp := b'== some earlier data ==')
+
+                       with self.assertRaises(SystemExit):
+                               sys.stdout, sys.stderr, sys_out, sys_err = out, 
err, sys.stdout, sys.stderr
+                               try:
+                                       pyaml.cli.main( argv=['-r', '-o', 
tmp.name],
+                                               stdin=io.StringIO(), 
stdout=out, stderr=err )
+                               finally: sys.stdout, sys.stderr = sys_out, 
sys_err
+                       self.assertEqual(out.getvalue(), '')
+                       self.assertGreater(len(err.getvalue()), 50)
+                       err.seek(0); err.truncate()
+
+                       st = os.stat(p := '/dev/null'); st_id = st.st_dev, 
st.st_ino
+                       pyaml.cli.main( argv=['-o', p], # shouldn't replace dev 
node
+                               stdin=io.StringIO(ys), stdout=out, stderr=err )
+                       self.assertEqual(out.getvalue(), '')
+                       self.assertEqual(err.getvalue(), '')
+                       tmp.seek(0); self.assertEqual(tmp.read(), d_tmp)
+                       st = os.stat(p); self.assertEqual((st.st_dev, 
st.st_ino), st_id)
+
+                       pyaml.cli.main( argv=['-o', tmp.name],
+                               stdin=io.StringIO(ys), stdout=out, stderr=err )
+                       self.assertEqual(out.getvalue(), '')
+                       self.assertEqual(err.getvalue(), '')
+                       tmp.seek(0); self.assertEqual(tmp.read(), d_tmp)
+                       with open(tmp.name) as tmp_repl: 
self.assertEqual(tmp_repl.read(), ys_pyaml)
+
 if __name__ == '__main__': unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyaml-25.7.0/pyaml.egg-info/PKG-INFO 
new/pyaml-26.2.1/pyaml.egg-info/PKG-INFO
--- old/pyaml-25.7.0/pyaml.egg-info/PKG-INFO    2025-07-10 20:44:48.000000000 
+0200
+++ new/pyaml-26.2.1/pyaml.egg-info/PKG-INFO    2026-02-06 14:49:27.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: pyaml
-Version: 25.7.0
+Version: 26.2.1
 Summary: PyYAML-based module to produce a bit more pretty and readable 
YAML-serialized data
 Home-page: https://github.com/mk-fg/pretty-yaml
 Author: Mike Kazantsev
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyaml-25.7.0/pyproject.toml 
new/pyaml-26.2.1/pyproject.toml
--- old/pyaml-25.7.0/pyproject.toml     2025-07-10 20:43:58.000000000 +0200
+++ new/pyaml-26.2.1/pyproject.toml     2026-02-06 14:48:21.000000000 +0100
@@ -1,7 +1,7 @@
 [project]
 
 name = "pyaml"
-version = "25.7.0"
+version = "26.2.1"
 
 description = "PyYAML-based module to produce a bit more pretty and readable 
YAML-serialized data"
 authors = [{name="Mike Kazantsev", email="[email protected]"}]

Reply via email to