Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-sphinxcontrib-plantuml for openSUSE:Factory checked in at 2024-01-03 12:24:04 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-sphinxcontrib-plantuml (Old) and /work/SRC/openSUSE:Factory/.python-sphinxcontrib-plantuml.new.28375 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sphinxcontrib-plantuml" Wed Jan 3 12:24:04 2024 rev:7 rq:1135617 version:0.27 Changes: -------- --- /work/SRC/openSUSE:Factory/python-sphinxcontrib-plantuml/python-sphinxcontrib-plantuml.changes 2022-12-06 14:23:10.717526166 +0100 +++ /work/SRC/openSUSE:Factory/.python-sphinxcontrib-plantuml.new.28375/python-sphinxcontrib-plantuml.changes 2024-01-03 12:24:08.901636554 +0100 @@ -1,0 +2,9 @@ +Fri Dec 29 09:49:50 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 0.27: + * add svg width height properties, override SVG style + * reformat sources with black, adjust flake8 rules accordingly + * remove redundant wheel dep from pyproject.toml + * create output file with unique file name + +------------------------------------------------------------------- Old: ---- sphinxcontrib-plantuml-0.24.1.tar.gz New: ---- sphinxcontrib-plantuml-0.27.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-sphinxcontrib-plantuml.spec ++++++ --- /var/tmp/diff_new_pack.13ucLW/_old 2024-01-03 12:24:09.805669585 +0100 +++ /var/tmp/diff_new_pack.13ucLW/_new 2024-01-03 12:24:09.805669585 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-sphinxcontrib-plantuml # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,11 +16,9 @@ # -%define skip_python2 1 -%{?!python_module:%define python_module() python3-%{**}} - +%{?sle15_python_module_pythons} Name: python-sphinxcontrib-plantuml -Version: 0.24.1 +Version: 0.27 Release: 0 Summary: Sphinx API for Web Apps License: BSD-2-Clause @@ -30,8 +28,9 @@ Patch0: py3-for-tests.patch BuildRequires: %{python_module Sphinx >= 2} BuildRequires: %{python_module Sphinx-latex} +BuildRequires: %{python_module pip} BuildRequires: %{python_module pytest} -BuildRequires: %{python_module setuptools} +BuildRequires: %{python_module wheel} BuildRequires: fdupes BuildRequires: ghostscript BuildRequires: python-rpm-macros @@ -54,10 +53,10 @@ %patch0 -p1 %build -%python_build +%pyproject_wheel %install -%python_install +%pyproject_install %python_expand %fdupes %{buildroot}%{$python_sitelib} %check @@ -72,5 +71,5 @@ %pycache_only %{python_sitelib}/sphinxcontrib/__pycache__ %{python_sitelib}/sphinxcontrib/plantuml.* %{python_sitelib}/sphinxcontrib_plantuml-%{version}-py*-nspkg.pth -%{python_sitelib}/sphinxcontrib_plantuml-%{version}-py*.*-info +%{python_sitelib}/sphinxcontrib_plantuml-%{version}.dist-info ++++++ sphinxcontrib-plantuml-0.24.1.tar.gz -> sphinxcontrib-plantuml-0.27.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.24.1/pyproject.toml new/plantuml-0.27/pyproject.toml --- old/plantuml-0.24.1/pyproject.toml 1970-01-01 01:00:00.000000000 +0100 +++ new/plantuml-0.27/pyproject.toml 2023-10-31 10:36:11.000000000 +0100 @@ -0,0 +1,6 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[tool.black] +skip-string-normalization = true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.24.1/setup.cfg new/plantuml-0.27/setup.cfg --- old/plantuml-0.24.1/setup.cfg 2022-11-18 04:35:48.000000000 +0100 +++ new/plantuml-0.27/setup.cfg 2023-10-31 10:36:11.000000000 +0100 @@ -8,10 +8,12 @@ [flake8] exclude = tests/fixture +# E203: whitespace before ':' (which disagrees with black) # E741: ambiguous variable name 'l' # W503: line break before binary operator -ignore = E741, W503 -max-line-length = 80 +ignore = E203, E741, W503 +# The default of black +max-line-length = 88 [options] install_requires = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.24.1/setup.py new/plantuml-0.27/setup.py --- old/plantuml-0.24.1/setup.py 2022-11-18 04:35:48.000000000 +0100 +++ new/plantuml-0.27/setup.py 2023-10-31 10:36:11.000000000 +0100 @@ -6,7 +6,7 @@ setup( name='sphinxcontrib-plantuml', - version='0.24.1', + version='0.27', url='https://github.com/sphinx-contrib/plantuml/', download_url='https://pypi.python.org/pypi/sphinxcontrib-plantuml', license='BSD', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.24.1/sphinxcontrib/plantuml.py new/plantuml-0.27/sphinxcontrib/plantuml.py --- old/plantuml-0.24.1/sphinxcontrib/plantuml.py 2022-11-18 04:35:48.000000000 +0100 +++ new/plantuml-0.27/sphinxcontrib/plantuml.py 2023-10-31 10:36:11.000000000 +0100 @@ -17,6 +17,7 @@ import shlex import shutil import subprocess +import tempfile from contextlib import contextmanager from docutils import nodes @@ -44,6 +45,7 @@ if os.name == 'nt': + def rename(src, dst): try: os.rename(src, dst) @@ -52,6 +54,7 @@ raise os.unlink(dst) os.rename(src, dst) + else: rename = os.rename @@ -90,6 +93,7 @@ Alice -> Bob: Hello Alice <- Bob: Hi """ + has_content = True required_arguments = 0 optional_arguments = 1 @@ -104,14 +108,19 @@ 'name': directives.unchanged, 'scale': directives.percentage, 'width': directives.length_or_percentage_or_unitless, + 'max-width': directives.length_or_percentage_or_unitless, } def run(self): warning = self.state.document.reporter.warning env = self.state.document.settings.env if self.arguments and self.content: - return [warning('uml directive cannot have both content and ' - 'a filename argument', line=self.lineno)] + return [ + warning( + 'uml directive cannot have both content and ' 'a filename argument', + line=self.lineno, + ) + ] if self.arguments: fn = i18n.search_image_for_language(self.arguments[0], env) relfn, absfn = env.relfn2path(fn) @@ -119,8 +128,12 @@ try: umlcode = _read_utf8(absfn) except (IOError, UnicodeDecodeError) as err: - return [warning('PlantUML file "%s" cannot be read: %s' - % (fn, err), line=self.lineno)] + return [ + warning( + 'PlantUML file "%s" cannot be read: %s' % (fn, err), + line=self.lineno, + ) + ] else: relfn = env.doc2path(env.docname, base=None) umlcode = '\n'.join(self.content) @@ -137,8 +150,9 @@ if 'align' in self.options: node['align'] = self.options['align'] if 'caption' in self.options: - inodes, messages = self.state.inline_text(self.options['caption'], - self.lineno) + inodes, messages = self.state.inline_text( + self.options['caption'], self.lineno + ) caption_node = nodes.caption(self.options['caption'], '', *inodes) caption_node.extend(messages) set_source_info(self, caption_node) @@ -174,8 +188,10 @@ fname = 'plantuml-%s.%s' % (key, fileformat) imgpath = getattr(self.builder, 'imgpath', None) if imgpath: - return ('/'.join((self.builder.imgpath, fname)), - os.path.join(self.builder.outdir, '_images', fname)) + return ( + '/'.join((self.builder.imgpath, fname)), + os.path.join(self.builder.outdir, '_images', fname), + ) else: return fname, os.path.join(self.builder.outdir, fname) @@ -227,16 +243,19 @@ def render_plantuml_inline(self, node, fileformat): absincdir = os.path.join(self.builder.srcdir, node['incdir']) try: - p = subprocess.Popen(generate_plantuml_args(self, node, fileformat), - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - cwd=absincdir) + p = subprocess.Popen( + generate_plantuml_args(self, node, fileformat), + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=absincdir, + ) except OSError as err: if err.errno != errno.ENOENT: raise - raise PlantUmlError('plantuml command %r cannot be run' - % self.builder.config.plantuml) + raise PlantUmlError( + 'plantuml command %r cannot be run' % self.builder.config.plantuml + ) sout, serr = p.communicate(node['uml'].encode('utf-8')) if p.returncode != 0: raise PlantUmlError('error while running plantuml\n\n%s' % serr) @@ -250,8 +269,9 @@ self.builder = builder self.batch_size = builder.config.plantuml_batch_size - self.cache_dir = os.path.join(builder.outdir, - builder.config.plantuml_cache_path) + self.cache_dir = os.path.join( + builder.outdir, builder.config.plantuml_cache_path + ) self._base_cmdargs = _split_cmdargs(builder.config.plantuml) self._base_cmdargs.extend(['-charset', 'utf-8']) @@ -286,8 +306,10 @@ outdir = os.path.join(self.cache_dir, key[:2]) outfbase = os.path.join(outdir, key) - if all(os.path.exists('%s.%s' % (outfbase, sfx)) - for sfx in ['puml'] + self.image_formats): + if all( + os.path.exists('%s.%s' % (outfbase, sfx)) + for sfx in ['puml'] + self.image_formats + ): continue ensuredir(outdir) @@ -308,10 +330,11 @@ pending_keys = sorted(self._pending_keys) for fileformat in self.image_formats: for i in range(0, len(pending_keys), self.batch_size): - keys = pending_keys[i:i + self.batch_size] + keys = pending_keys[i : i + self.batch_size] with util.progress_message( - 'rendering plantuml diagrams [%d..%d/%d]' - % (i, i + len(keys), len(pending_keys))): + 'rendering plantuml diagrams [%d..%d/%d]' + % (i, i + len(keys), len(pending_keys)) + ): self._render_files(keys, fileformat) del self._pending_keys[:] @@ -321,50 +344,67 @@ cmdargs.extend(_ARGS_BY_FILEFORMAT[fileformat]) cmdargs.extend(os.path.join(k[:2], '%s.puml' % k) for k in keys) try: - p = subprocess.Popen(cmdargs, stderr=subprocess.PIPE, - cwd=self.cache_dir) + p = subprocess.Popen(cmdargs, stderr=subprocess.PIPE, cwd=self.cache_dir) except OSError as err: if err.errno != errno.ENOENT: raise - raise PlantUmlError('plantuml command %r cannot be run' - % self.builder.config.plantuml) + raise PlantUmlError( + 'plantuml command %r cannot be run' % self.builder.config.plantuml + ) serr = p.communicate()[1] if p.returncode != 0: if self.builder.config.plantuml_syntax_error_image: - logger.warning('error while running plantuml\n\n%s' % serr) + logger.warning( + 'error while running plantuml\n\n%s' % serr, type='plantuml' + ) else: raise PlantUmlError('error while running plantuml\n\n%s' % serr) def render(self, node, fileformat): key = hash_plantuml_node(node) outdir = os.path.join(self.cache_dir, key[:2]) - outfname = os.path.join(outdir, '%s.%s' % (key, fileformat)) + basename = '%s.%s' % (key, fileformat) + outfname = os.path.join(outdir, basename) if os.path.exists(outfname): return outfname ensuredir(outdir) absincdir = os.path.join(self.builder.srcdir, node['incdir']) - with open(outfname + '.new', 'wb') as f: + # TODO: delete_on_close can be used on Python 3.12+ + with tempfile.NamedTemporaryFile( + prefix=basename + '.new', dir=outdir, delete=False + ) as f: try: - p = subprocess.Popen(generate_plantuml_args(self, node, - fileformat), - stdout=f, stdin=subprocess.PIPE, - stderr=subprocess.PIPE, - cwd=absincdir) + p = subprocess.Popen( + generate_plantuml_args(self, node, fileformat), + stdout=f, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=absincdir, + ) except OSError as err: if err.errno != errno.ENOENT: raise - raise PlantUmlError('plantuml command %r cannot be run' - % self.builder.config.plantuml) + raise PlantUmlError( + 'plantuml command %r cannot be run' % self.builder.config.plantuml + ) serr = p.communicate(node['uml'].encode('utf-8'))[1] if p.returncode != 0: if self.builder.config.plantuml_syntax_error_image: - logger.warning('error while running plantuml\n\n%s' % serr) + logger.warning( + 'error while running plantuml\n\n%s' % serr, + location=node, + type='plantuml', + ) else: - raise PlantUmlError('error while running plantuml\n\n%s' - % serr) + raise PlantUmlError('error while running plantuml\n\n%s' % serr) + + # inherit dir mode since temp file isn't world-readable by default. + if os.name == 'posix': + os.fchmod(f.fileno(), os.lstat(outdir).st_mode & 0o666) + f.close() + rename(f.name, outfname) - rename(outfname + '.new', outfname) return outfname @@ -380,12 +420,16 @@ # process images prior to html_vist. scale_attrs = [k for k in ('scale', 'width', 'height') if k in node] if scale_attrs and Image is None: - logger.warning(('plantuml: unsupported scaling attributes: %s ' - '(install PIL or Pillow)' - % ', '.join(scale_attrs))) + logger.warning( + ( + 'plantuml: unsupported scaling attributes: %s ' + '(install PIL or Pillow)' % ', '.join(scale_attrs) + ), + location=node, + type='plantuml', + ) if not scale_attrs or Image is None: - return ('<img src="%s" alt="%s"/>\n' - % (self.encode(refname), self.encode(alt))) + return '<img src="%s" alt="%s"/>\n' % (self.encode(refname), self.encode(alt)) scale = node.get('scale', 100) styles = [] @@ -410,17 +454,23 @@ try: im = Image.open(outfname) im.load() - styles.extend('%s: %s%s' % (a, w * scale / 100, 'px') - for a, w in zip(['width', 'height'], im.size)) + styles.extend( + '%s: %s%s' % (a, w * scale / 100, 'px') + for a, w in zip(['width', 'height'], im.size) + ) except (IOError, OSError) as err: - logger.warning('plantuml: failed to get image size: %s' % err) - - return ('<a href="%s"><img src="%s" alt="%s" style="%s"/>' - '</a>\n' - % (self.encode(refname), - self.encode(refname), - self.encode(alt), - self.encode('; '.join(styles)))) + logger.warning( + 'plantuml: failed to get image size: %s' % err, + location=node, + type='plantuml', + ) + + return '<a href="%s"><img src="%s" alt="%s" style="%s"/>' '</a>\n' % ( + self.encode(refname), + self.encode(refname), + self.encode(alt), + self.encode('; '.join(styles)), + ) def _get_svg_style(fname): @@ -442,30 +492,48 @@ return m.group(1) +def _svg_get_style_str(node, outfname): + width_height_styles = [ + "%s:%s" % (key, val) + for key, val in node.attributes.items() + if key in ['width', 'height', 'max-width'] + ] + if width_height_styles: + style_str = '; '.join(width_height_styles) + else: + style_str = _get_svg_style(outfname) or '' + return style_str + + def _get_svg_tag(self, fnames, node): refname, outfname = fnames['svg'] - return '\n'.join([ - # copy width/height style from <svg> tag, so that <object> area - # has enough space. - '<object data="%s" type="image/svg+xml" style="%s">' % ( - self.encode(refname), _get_svg_style(outfname) or ''), - _get_png_tag(self, fnames, node), - '</object>']) + style_str = _svg_get_style_str(node, outfname) + return '\n'.join( + [ + # copy width/height style from <svg> tag, so that <object> area + # has enough space. + '<object data="%s" type="image/svg+xml" style="%s">' + % (self.encode(refname), style_str), + _get_png_tag(self, fnames, node), + '</object>', + ] + ) def _get_svg_img_tag(self, fnames, node): refname, outfname = fnames['svg'] alt = node.get('alt', node['uml']) - return ('<img src="%s" alt="%s"/>' - % (self.encode(refname), self.encode(alt))) + return '<img src="%s" alt="%s"/>' % (self.encode(refname), self.encode(alt)) def _get_svg_obj_tag(self, fnames, node): refname, outfname = fnames['svg'] # copy width/height style from <svg> tag, so that <object> area # has enough space. - return ('<object data="%s" type="image/svg+xml" style="%s"></object>' - % (self.encode(refname), _get_svg_style(outfname) or '')) + return '<object data="%s" type="image/svg+xml" style="%s"></object>' % ( + self.encode(refname), + _get_svg_style(outfname) or '', + ) _KNOWN_HTML_FORMATS = { @@ -482,18 +550,19 @@ except KeyError: raise PlantUmlError( 'plantuml_output_format must be one of %s, but is %r' - % (', '.join(map(repr, _KNOWN_HTML_FORMATS)), fmt)) + % (', '.join(map(repr, _KNOWN_HTML_FORMATS)), fmt) + ) @contextmanager -def _prepare_html_render(self, fmt): +def _prepare_html_render(self, fmt, node): if fmt == 'none': raise nodes.SkipNode try: yield _lookup_html_format(fmt) except PlantUmlError as err: - logger.warning(str(err)) + logger.warning(str(err), location=node, type='plantuml') raise nodes.SkipNode @@ -504,10 +573,9 @@ else: fmt = self.builder.config.plantuml_output_format - with _prepare_html_render(self, fmt) as (fileformats, gettag): + with _prepare_html_render(self, fmt, node) as (fileformats, gettag): # fnames: {fileformat: (refname, outfname), ...} - fnames = dict((e, render_plantuml(self, node, e)) - for e in fileformats) + fnames = dict((e, render_plantuml(self, node, e)) for e in fileformats) self.body.append(self.starttag(node, 'p', CLASS='plantuml')) self.body.append(gettag(self, fnames, node)) @@ -520,19 +588,20 @@ args.append(fname) try: try: - p = subprocess.Popen(args, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError as err: # workaround for missing shebang of epstopdf script if err.errno != getattr(errno, 'ENOEXEC', 0): raise - p = subprocess.Popen(['bash'] + args, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + p = subprocess.Popen( + ['bash'] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) except OSError as err: if err.errno != errno.ENOENT: raise - raise PlantUmlError('epstopdf command %r cannot be run' - % self.builder.config.plantuml_epstopdf) + raise PlantUmlError( + 'epstopdf command %r cannot be run' % self.builder.config.plantuml_epstopdf + ) serr = p.communicate()[1] if p.returncode != 0: raise PlantUmlError('error while running epstopdf\n\n%s' % serr) @@ -553,7 +622,8 @@ except KeyError: raise PlantUmlError( 'plantuml_latex_output_format must be one of %s, but is %r' - % (', '.join(map(repr, _KNOWN_LATEX_FORMATS)), fmt)) + % (', '.join(map(repr, _KNOWN_LATEX_FORMATS)), fmt) + ) def _latex_adjustbox_options(self, node): @@ -574,8 +644,7 @@ adjustbox_options.append('height=%s' % h) if 'scale' in node: if not adjustbox_options: - adjustbox_options.append('scale=%s' - % (float(node['scale']) / 100.0)) + adjustbox_options.append('scale=%s' % (float(node['scale']) / 100.0)) return adjustbox_options @@ -600,7 +669,7 @@ refname, outfname = render_plantuml(self, node, fileformat) refname, outfname = postproc(self, refname, outfname) except PlantUmlError as err: - logger.warning(str(err)) + logger.warning(str(err), location=node, type='plantuml') raise nodes.SkipNode if fmt == 'tikz': @@ -644,7 +713,8 @@ if fmt not in _KNOWN_CONFLUENCE_FORMATS: raise PlantUmlError( 'plantuml_output_format must be one of %s, but is %r' - % (', '.join(map(repr, _KNOWN_CONFLUENCE_FORMATS)), fmt)) + % (', '.join(map(repr, _KNOWN_CONFLUENCE_FORMATS)), fmt) + ) _, outfname = render_plantuml(self, node, fmt) @@ -663,7 +733,7 @@ try: text = render_plantuml_inline(self, node, 'txt') except PlantUmlError as err: - logger.warning(str(err)) + logger.warning(str(err), location=node, type='plantuml') text = node['uml'] # fall back to uml text, which is still readable self.new_state() @@ -678,14 +748,18 @@ refname, outfname = render_plantuml(self, node, 'eps') refname, outfname = _convert_eps_to_pdf(self, refname, outfname) except PlantUmlError as err: - logger.warning(str(err)) + logger.warning(str(err), location=node, type='plantuml') raise nodes.SkipNode rep = nodes.image(uri=outfname, alt=node.get('alt', node['uml'])) node.parent.replace(node, rep) def unsupported_visit_plantuml(self, node): - logger.warning('plantuml: unsupported output format (node skipped)') + logger.warning( + 'plantuml: unsupported output format (node skipped)', + location=node, + type='plantuml', + ) raise nodes.SkipNode @@ -723,8 +797,7 @@ app.add_node(plantuml, **_NODE_VISITORS) app.add_directive('uml', UmlDirective) try: - app.add_config_value('plantuml', 'plantuml', 'html', - types=(str, tuple, list)) + app.add_config_value('plantuml', 'plantuml', 'html', types=(str, tuple, list)) except TypeError: # Sphinx < 1.4? app.add_config_value('plantuml', 'plantuml', 'html') @@ -741,6 +814,7 @@ # imitate what app.add_node() does if 'rst2pdf.pdfbuilder' in app.config.extensions: from rst2pdf.pdfbuilder import PDFTranslator as translator + setattr(translator, 'visit_' + plantuml.__name__, pdf_visit_plantuml) return {'parallel_read_safe': True}