Hello community, here is the log from the commit of package i18nspector for openSUSE:Factory checked in at 2017-08-18 15:06:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/i18nspector (Old) and /work/SRC/openSUSE:Factory/.i18nspector.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "i18nspector" Fri Aug 18 15:06:28 2017 rev:25 rq:517451 version:0.25.4 Changes: -------- --- /work/SRC/openSUSE:Factory/i18nspector/i18nspector.changes 2016-08-31 14:31:47.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.i18nspector.new/i18nspector.changes 2017-08-18 15:06:38.803202544 +0200 @@ -1,0 +2,10 @@ +Thu Aug 17 09:09:14 UTC 2017 - lazy.k...@opensuse.org + +- Update to 0.25.4. + * Fix crash when checking Python brace formats string that have + both named and numbered arguments. + * Reorder sections in the manual page, as per man-pages(7) + recommendations. + * Put license into a separate file. + +------------------------------------------------------------------- Old: ---- i18nspector-0.25.3.tar.gz i18nspector-0.25.3.tar.gz.asc New: ---- i18nspector-0.25.4.tar.gz i18nspector-0.25.4.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ i18nspector.spec ++++++ --- /var/tmp/diff_new_pack.8jMH1k/_old 2017-08-18 15:06:40.682937804 +0200 +++ /var/tmp/diff_new_pack.8jMH1k/_new 2017-08-18 15:06:40.686937241 +0200 @@ -1,7 +1,7 @@ # # spec file for package i18nspector # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: i18nspector -Version: 0.25.3 +Version: 0.25.4 Release: 0 Summary: Tool for Checking gettext POT/PO/MO Files License: MIT @@ -66,7 +66,7 @@ %files %defattr(-,root,root,-) -%doc doc/{changelog,tags.txt,todo.txt} +%doc doc/{changelog,LICENSE,tags.txt,todo.txt} %{_bindir}/%{name} %{_datadir}/%{name}/ %{_mandir}/man?/* ++++++ i18nspector-0.25.3.tar.gz -> i18nspector-0.25.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/.coveragerc new/i18nspector-0.25.4/.coveragerc --- old/i18nspector-0.25.3/.coveragerc 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/.coveragerc 2017-06-23 18:25:45.000000000 +0200 @@ -3,10 +3,9 @@ [report] show_missing = true -exclude_lines = +exclude_lines = # no coverage \A\s+raise misc[.]DataIntegrityError\b \A\s+raise NotImplementedError\b \A\s+pass\Z - <no-coverage> # vim:ft=dosini ts=4 sts=4 sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/.pylintrc new/i18nspector-0.25.4/.pylintrc --- old/i18nspector-0.25.3/.pylintrc 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/.pylintrc 2017-06-23 18:25:45.000000000 +0200 @@ -5,8 +5,10 @@ duplicate-code, fixme, invalid-name, + len-as-condition, locally-disabled, locally-enabled, + no-else-return, no-self-use, redefined-variable-type, superfluous-parens, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/Makefile new/i18nspector-0.25.4/Makefile --- old/i18nspector-0.25.3/Makefile 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/Makefile 2017-06-23 18:25:45.000000000 +0200 @@ -1,4 +1,4 @@ -# Copyright © 2012-2013 Jakub Wilk <jw...@jwilk.net> +# Copyright © 2012-2016 Jakub Wilk <jw...@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -46,8 +46,12 @@ # library + data: ( find lib data -type f ! -name '*.py[co]' ) \ | xargs -t -I {} $(INSTALL) -p -D -m644 {} $(DESTDIR)$(basedir)/{} +ifeq "$(wildcard .git doc/$(exe).1)" ".git" + # run "make -C doc" to build the manpage +else # manual page: $(INSTALL) -p -D -m644 doc/$(exe).1 $(DESTDIR)$(mandir)/man1/$(exe).1 +endif .PHONY: test test: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/data/string-formats new/i18nspector-0.25.4/data/string-formats --- old/i18nspector-0.25.3/data/string-formats 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/data/string-formats 2017-06-23 18:25:45.000000000 +0200 @@ -46,10 +46,10 @@ # http://www.lua.org/manual/5.2/manual.html#pdf-string.format objc = %d -# https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html +# https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html object-pascal = %d -# http://www.freepascal.org/docs-html/rtl/sysutils/format.html +# https://www.freepascal.org/docs-html/rtl/sysutils/format.html perl = %d # http://perldoc.perl.org/functions/sprintf.html diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/doc/LICENSE new/i18nspector-0.25.4/doc/LICENSE --- old/i18nspector-0.25.3/doc/LICENSE 1970-01-01 01:00:00.000000000 +0100 +++ new/i18nspector-0.25.4/doc/LICENSE 2017-06-23 18:25:45.000000000 +0200 @@ -0,0 +1,19 @@ +Copyright © 2012-2017 Jakub Wilk <jw...@jwilk.net> + +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. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/doc/Makefile new/i18nspector-0.25.4/doc/Makefile --- old/i18nspector-0.25.3/doc/Makefile 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/doc/Makefile 2017-06-23 18:25:45.000000000 +0200 @@ -1,4 +1,4 @@ -# Copyright © 2012-2015 Jakub Wilk <jw...@jwilk.net> +# Copyright © 2012-2016 Jakub Wilk <jw...@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -32,9 +32,10 @@ $(exe).1: $(exe).txt tags.txt $(rst2man) --input-encoding=UTF-8:strict < $(<) > $(@).tmp - sed -i -e '/^[.]BI/ {s/\\fP/\\fR/g}' $(@).tmp # work-around for https://bugs.debian.org/806601 + sed -i -e '/^[.]BI/ { s/\\fP/\\fR/g; }' $(@).tmp # work-around for https://bugs.debian.org/806601 sed -i -e 's/^[.]de1/.de/' $(@).tmp # work-around for https://bugs.debian.org/710678 sed -i -e "s/\([a-z]\)\\\\(aq\([a-z]\)/\1'\2/g" $(@).tmp # prefer ' to \(aq when used as an apostrophe + sed -i -e '/.\" vim:/d' $(@).tmp mv $(@).tmp $(@) .PHONY: clean diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/doc/changelog new/i18nspector-0.25.4/doc/changelog --- old/i18nspector-0.25.3/doc/changelog 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/doc/changelog 2017-06-23 18:25:45.000000000 +0200 @@ -1,3 +1,12 @@ +i18nspector (0.25.4) unstable; urgency=low + + * Fix crash when checking Python brace formats string that have both named + and numbered arguments. + * Reorder sections in the manual page, as per man-pages(7) recommendations. + * Put license into a separate file. + + -- Jakub Wilk <jw...@jwilk.net> Fri, 23 Jun 2017 18:25:35 +0200 + i18nspector (0.25.3) unstable; urgency=low * Rewrite shebang at install time. @@ -194,7 +203,7 @@ arguments than corresponding msgid/msgid_plural. Thanks to Guillem Jover for the bug report. https://bugs.debian.org/753946 - * Check for previous msgid annotations (#| msgid ...) attached to non-fuzzy + * Check for previous msgid annotations (“#| msgid …”) attached to non-fuzzy messages. * Check for plural Qt format string mistakenly tagged as C format strings. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/doc/i18nspector.1 new/i18nspector-0.25.4/doc/i18nspector.1 --- old/i18nspector-0.25.3/doc/i18nspector.1 2016-08-29 13:27:21.000000000 +0200 +++ new/i18nspector-0.25.4/doc/i18nspector.1 2017-06-23 18:25:57.000000000 +0200 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH I18NSPECTOR 1 "2016-08-29" "i18nspector 0.25.3" "" +.TH I18NSPECTOR 1 "2017-06-23" "i18nspector 0.25.4" "" .SH NAME i18nspector \- checking tool for gettext POT, PO and MO files . @@ -33,6 +33,12 @@ .SH SYNOPSIS .sp \fBi18nspector\fP [\fIoptions\fP] \fIfile\fP [\fIfile\fP …] +.SH DESCRIPTION +.sp +\fBi18nspector\fP is a tool for checking translation templates (POT), message +catalogues (PO) and compiled message catalogues (MO) files for common problems. +These files are used by the GNU gettext translation functions and tools in +many different development environments. .SH OPTIONS .INDENT 0.0 .TP @@ -56,12 +62,7 @@ .B \-\-version Show the program's version information and exit. .UNINDENT -.SH DESCRIPTION -.sp -\fBi18nspector\fP is a tool for checking translation templates (POT), message -catalogues (PO) and compiled message catalogues (MO) files for common problems. -These files are used by the GNU gettext translation functions and tools in -many different development environments. +.SH OUTPUT FORMAT .sp The following format is used for all the reported problems: .sp @@ -2375,7 +2376,6 @@ .SH SEE ALSO .sp \fBmsgfmt\fP(1), particularly the \fB\-c\fP option -.\" vim:ft=rst ts=3 sts=3 sw=3 . .\" Generated by docutils manpage writer. . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/doc/i18nspector.txt new/i18nspector-0.25.4/doc/i18nspector.txt --- old/i18nspector-0.25.3/doc/i18nspector.txt 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/doc/i18nspector.txt 2017-06-23 18:25:45.000000000 +0200 @@ -7,13 +7,20 @@ ---------------------------------------------- :manual section: 1 -:version: i18nspector 0.25.3 +:version: i18nspector 0.25.4 :date: |date| Synopsis -------- **i18nspector** [*options*] *file* [*file* …] +Description +----------- +**i18nspector** is a tool for checking translation templates (POT), message +catalogues (PO) and compiled message catalogues (MO) files for common problems. +These files are used by the GNU gettext translation functions and tools in +many different development environments. + Options ------- -l lang, --language lang @@ -32,12 +39,8 @@ --version Show the program's version information and exit. -Description ------------ -**i18nspector** is a tool for checking translation templates (POT), message -catalogues (PO) and compiled message catalogues (MO) files for common problems. -These files are used by the GNU gettext translation functions and tools in -many different development environments. +Output format +------------- The following format is used for all the reported problems: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/doc/todo.txt new/i18nspector-0.25.4/doc/todo.txt --- old/i18nspector-0.25.3/doc/todo.txt 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/doc/todo.txt 2017-06-23 18:25:45.000000000 +0200 @@ -85,7 +85,7 @@ Add option for disabling/forcing colored output. -Use `blessings <https://pypi.python.org/pypi/blessings/>`_ for colored output. +Use `blessings <https://pypi.python.org/pypi/blessings>`_ for colored output. Reimplement the EUC-TW codec with PyICU. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/__init__.py new/i18nspector-0.25.4/lib/__init__.py --- old/i18nspector-0.25.3/lib/__init__.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/__init__.py 2017-06-23 18:25:45.000000000 +0200 @@ -0,0 +1,6 @@ +''' +i18nspector's private modules +''' + +# pylint: disable=pointless-statement +... # Python >= 3 is required diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/check/msgformat/__init__.py new/i18nspector-0.25.4/lib/check/msgformat/__init__.py --- old/i18nspector-0.25.3/lib/check/msgformat/__init__.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/check/msgformat/__init__.py 2017-06-23 18:25:45.000000000 +0200 @@ -155,16 +155,16 @@ omitted_int_conv_ok=d.omitted_int_conv_ok, ) - def check_msgids(self, message, msgid_formats): - pass + def check_msgids(self, message, msgid_fmts): + pass # no coverage @abc.abstractmethod def check_string(self, ctx, message, s): - return + pass # no coverage @abc.abstractmethod def check_args(self, message, src_loc, src_fmt, dst_loc, dst_fmt, *, omitted_int_conv_ok=False): - return + pass # no coverage __all__ = ['Checker'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/check/msgformat/c.py new/i18nspector-0.25.4/lib/check/msgformat/c.py --- old/i18nspector-0.25.3/lib/check/msgformat/c.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/check/msgformat/c.py 2017-06-23 18:25:45.000000000 +0200 @@ -62,7 +62,7 @@ tags.safestr(', '.join(sorted(x for x in exc.args[2]))), ) except backend.FlagError as exc: - [conv, flag] = exc.args + [conv, flag] = exc.args # pylint: disable=unbalanced-tuple-unpacking self.tag('c-format-string-error', prefix, tags.safestr(exc.message), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/check/msgformat/pybrace.py new/i18nspector-0.25.4/lib/check/msgformat/pybrace.py --- old/i18nspector-0.25.3/lib/check/msgformat/pybrace.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/check/msgformat/pybrace.py 2017-06-23 18:25:45.000000000 +0200 @@ -1,3 +1,23 @@ +# Copyright © 2016-2017 Jakub Wilk <jw...@jwilk.net> +# +# 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. + ''' message format checks: Python's str.format() ''' @@ -28,10 +48,12 @@ return fmt def check_args(self, message, src_loc, src_fmt, dst_loc, dst_fmt, *, omitted_int_conv_ok=False): + def sort_key(item): + return (isinstance(item, str), item) prefix = message_repr(message, template='{}:') src_args = src_fmt.argument_map dst_args = dst_fmt.argument_map - for key in sorted(dst_args.keys() & src_args.keys()): + for key in sorted(dst_args.keys() & src_args.keys(), key=sort_key): src_arg = src_args[key][0] dst_arg = dst_args[key][0] if not (src_arg.types & dst_arg.types): @@ -39,7 +61,7 @@ tags.safestr(', '.join(dst_arg.types)), tags.safestr('({})'.format(dst_loc)), '!=', tags.safestr(', '.join(src_arg.types)), tags.safestr('({})'.format(src_loc)), ) - for key in sorted(dst_args.keys() - src_args.keys()): + for key in sorted(dst_args.keys() - src_args.keys(), key=sort_key): self.tag('python-brace-format-string-unknown-argument', prefix, key, tags.safestr('in'), tags.safestr(dst_loc), tags.safestr('but not in'), tags.safestr(src_loc), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/check/msgformat/python.py new/i18nspector-0.25.4/lib/check/msgformat/python.py --- old/i18nspector-0.25.3/lib/check/msgformat/python.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/check/msgformat/python.py 2017-06-23 18:25:45.000000000 +0200 @@ -39,7 +39,7 @@ try: fmt = backend.FormatString(s) except backend.ArgumentTypeMismatch as exc: - [s, key, types] = exc.args + [s, key, types] = exc.args # pylint: disable=unbalanced-tuple-unpacking self.tag('python-format-string-error', prefix, tags.safestr(exc.message), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/cli.py new/i18nspector-0.25.4/lib/cli.py --- old/i18nspector-0.25.3/lib/cli.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/cli.py 2017-06-23 18:25:45.000000000 +0200 @@ -39,7 +39,7 @@ from lib import tags from lib import terminal -__version__ = '0.25.3' +__version__ = '0.25.4' def initialize_terminal(): if sys.stdout.isatty(): @@ -157,7 +157,7 @@ class VersionAction(argparse.Action): def __init__(self, option_strings, dest=argparse.SUPPRESS): - super(VersionAction, self).__init__( + super().__init__( option_strings=option_strings, dest=dest, nargs=0, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/encodings.py new/i18nspector-0.25.4/lib/encodings.py --- old/i18nspector-0.25.3/lib/encodings.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/encodings.py 2017-06-23 18:25:45.000000000 +0200 @@ -41,7 +41,7 @@ def __init__(self, encoding): LookupError.__init__(self, 'unknown encoding: ' + encoding) -def _not_implemented(*args, **kwargs): +def _not_implemented(*args, **kwargs): # no coverage del args, kwargs raise NotImplementedError @@ -190,7 +190,7 @@ return False except LookupError: pass - except Exception: # pylint: disable=broad-except + except Exception: # no coverage; pylint: disable=broad-except pass if missing_ok: return False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/iconv.py new/i18nspector-0.25.4/lib/iconv.py --- old/i18nspector-0.25.3/lib/iconv.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/iconv.py 2017-06-23 18:25:45.000000000 +0200 @@ -53,7 +53,7 @@ def _popen(*args): def set_lc_all_c(): - os.environ['LC_ALL'] = 'C' # <no-coverage> + os.environ['LC_ALL'] = 'C' # no coverage return ipc.Popen(args, stdin=ipc.PIPE, stdout=ipc.PIPE, stderr=ipc.PIPE, preexec_fn=set_lc_all_c, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/intexpr.py new/i18nspector-0.25.4/lib/intexpr.py --- old/i18nspector-0.25.3/lib/intexpr.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/intexpr.py 2017-06-23 18:25:45.000000000 +0200 @@ -168,7 +168,7 @@ def _visit(self, node, *args): try: fn = getattr(self, '_visit_' + type(node).__name__.lower()) - except KeyError: # <no-coverage> + except KeyError: # no coverage raise NotImplementedError(type(node).__name__) return fn(node, *args) @@ -673,7 +673,7 @@ def __init__(self, node): if not isinstance(node, ast.Expr): - raise TypeError # <no-coverage> + raise TypeError # no coverage self._node = node def __call__(self, n, *, bits=32): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/ling.py new/i18nspector-0.25.4/lib/ling.py --- old/i18nspector-0.25.3/lib/ling.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/ling.py 2017-06-23 18:25:45.000000000 +0200 @@ -56,7 +56,7 @@ def __init__(self, language_code, territory_code=None, encoding=None, modifier=None): self.language_code = language_code if language_code is None: - raise TypeError('language_code must not be None') # <no-coverage> + raise TypeError('language_code must not be None') # no coverage self.territory_code = territory_code self.encoding = None if encoding is not None: @@ -108,7 +108,7 @@ raise FixingLanguageCodesFailed() elif cc != self.territory_code: # This shouldn't really happen, but better safe than sorry. - raise ValueError # <no-coverage> + raise ValueError # no coverage # TODO: ll_CC could be still incorrect, even when both ll and CC are # correct. self.language_code = ll @@ -253,7 +253,7 @@ continue try: _primary_languages[ll] - except LookupError: # <no-coverage> + except LookupError: # no coverage raise misc.DataIntegrityError [_primary_languages, _name_to_code] = _read_primary_languages() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/misc.py new/i18nspector-0.25.4/lib/misc.py --- old/i18nspector-0.25.3/lib/misc.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/misc.py 2017-06-23 18:25:45.000000000 +0200 @@ -91,7 +91,7 @@ Namespace() # make pyflakes and coverage.py happy -if sys.version_info >= (3, 3): # <no-coverage> +if sys.version_info >= (3, 3): # no coverage Namespace = types.SimpleNamespace @contextlib.contextmanager diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/strformat/c.py new/i18nspector-0.25.4/lib/strformat/c.py --- old/i18nspector-0.25.3/lib/strformat/c.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/strformat/c.py 2017-06-23 18:25:45.000000000 +0200 @@ -255,7 +255,7 @@ if conv is not arg: return else: - assert False, 'type(arg) == {!r}'.format(type(arg)) # <no-coverage> + assert False, 'type(arg) == {!r}'.format(type(arg)) # no coverage if conv is None: return if not conv.integer: @@ -291,7 +291,7 @@ tp = 'uint' else: # should not happen - assert False # <no-coverage> + assert False # no coverage conversion = c99conversion if c99length.startswith(('LEAST', 'FAST')): tp += '_' + c99length.lower() @@ -356,7 +356,7 @@ tp = 'void' else: # should not happen - assert False # <no-coverage> + assert False # no coverage if tp is None: assert length is not None raise LengthError(s, length) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/strformat/python.py new/i18nspector-0.25.4/lib/strformat/python.py --- old/i18nspector-0.25.3/lib/strformat/python.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/strformat/python.py 2017-06-23 18:25:45.000000000 +0200 @@ -297,7 +297,7 @@ elif conv == '%': tp = 'None' else: - assert False # <no-coverage> + assert False # no coverage self.type = tp if tp == 'None': if key is not None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/lib/terminal.py new/i18nspector-0.25.4/lib/terminal.py --- old/i18nspector-0.25.3/lib/terminal.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/lib/terminal.py 2017-06-23 18:25:45.000000000 +0200 @@ -95,7 +95,7 @@ try: _curses.tigetstr('x') except TypeError: - # curses.tigetstr() is broken in PyPy3: + # curses.tigetstr() is broken in PyPy 3: # https://bitbucket.org/pypy/pypy/issues/1997 _curses = _dummy_curses return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/private/check-rst new/i18nspector-0.25.4/private/check-rst --- old/i18nspector-0.25.3/private/check-rst 1970-01-01 01:00:00.000000000 +0100 +++ new/i18nspector-0.25.4/private/check-rst 2017-06-23 18:25:45.000000000 +0200 @@ -0,0 +1,36 @@ +#!/bin/sh + +# Copyright © 2016-2017 Jakub Wilk <jw...@jwilk.net> +# +# 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. + +here=$(dirname "$0") +rst2xml=$(command -v rst2xml) \ +|| rst2xml=$(command -v rst2xml.py) \ +|| { printf 'rst2xml not found\n' >&2; exit 1; } +options='--input-encoding=UTF-8 --output-encoding=UTF-8 --strict' +if [ $# -eq 0 ] +then + grep -rwl 'ft=rst' doc/ +else + printf '%s\n' "$@" +fi | +xargs -L1 -t -I{} "$rst2xml" $options {} /dev/null + +# vim:ts=4 sts=4 sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/private/online-build-po-corpus new/i18nspector-0.25.4/private/online-build-po-corpus --- old/i18nspector-0.25.3/private/online-build-po-corpus 1970-01-01 01:00:00.000000000 +0100 +++ new/i18nspector-0.25.4/private/online-build-po-corpus 2017-06-23 18:25:45.000000000 +0200 @@ -0,0 +1,225 @@ +#!/usr/bin/env python3 + +# Copyright © 2012-2017 Jakub Wilk <jw...@jwilk.net> +# +# 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. + +import argparse +import contextlib +import gzip +import os +import re +import subprocess +import sys +import tarfile +import tempfile +import unittest.mock +import urllib.parse + +import apt +import apt_pkg + +with unittest.mock.patch.dict(os.environ, PATH='/nonexistent'): + # tqdm wants to execute git for no good reason: + # https://github.com/tqdm/tqdm/issues/328 + # Let's foil this plan: + import tqdm + +def is_po_path(path): + return path.endswith(('.po', '.pot')) + +class Fetcher(object): + + def __init__(self, urlbase): + self._urlbase = urlbase + self._progress = apt.progress.text.AcquireProgress() + self._acquire = apt_pkg.Acquire(self._progress) + self._files = [] + self._tmpdir = tempfile.TemporaryDirectory(prefix='i18nspector.private.') + + def add(self, url, name): + url = urllib.parse.urljoin(self._urlbase, url) + self._files += [apt_pkg.AcquireFile( + self._acquire, + uri=url, + descr=url, + destfile=os.path.join(self._tmpdir.name, name) + )] + + def run(self): + acq = self._acquire + rc = acq.run() + if rc != acq.RESULT_CONTINUE: + raise RuntimeError('fetching failed') + for acqfile in self._files: + if acqfile.status != acqfile.STAT_DONE: + raise RuntimeError('fetching failed') + yield acqfile.destfile + + def __enter__(self): + return self + + def __exit__(self, exc, value, tb): + self.close() + + def close(self): + self._tmpdir.cleanup() + +_package_name_re = re.compile(r'\A[a-z0-9][a-z0-9.+-]+\Z') +def validate_package_name(pkg): + if _package_name_re.match(pkg): + pass + else: + raise RuntimeError('invalid package name: {pkg!r}'.format(pkg=pkg)) + +@contextlib.contextmanager +def chdir(new_cwd): + orig_cwd = os.getcwd() + try: + os.chdir(new_cwd) + yield + finally: + os.chdir(orig_cwd) + +default_mirror = 'http://deb.debian.org/debian' +default_dist = 'stable' +default_areas = 'main' + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument('--mirror', metavar='URL', default=default_mirror, + help='Debian mirror to use (default: {mirror})'.format(mirror=default_mirror) + ) + ap.add_argument('--distribution', metavar='DIST', default=default_dist, + help='Debian distribution to use (default: {dist})'.format(dist=default_dist) + ) + ap.add_argument('--areas', metavar='AREA[,AREA...]', default=default_areas, + help='archive areas to use (default: {areas})'.format(areas=default_areas) + ) + ap.add_argument('--output', metavar='TARFILE', required=True, + help='output tar file' + ) + options = ap.parse_args() + output = options.output + tarmode = 'w|' + for ext in 'gz', 'bz2', 'xz': + if options.output.endswith('.' + ext): + tarmode += ext + break + tar = tarfile.open(output, mode=tarmode) + mirror = options.mirror + dist = options.distribution + areas = options.areas.split(',') + def tarfilter(tarinfo): + tarinfo.uid = tarinfo.gid = 0 + tarinfo.uname = tarinfo.gname = 'root' + tarinfo.mode &= 0o700 + tarinfo.mode |= 0o644 + if tarinfo.mode & 0o100: + tarinfo.mode |= 0o111 + tarinfo.name = 'po-corpus-{dist}/{name}'.format(dist=dist, name=tarinfo.name) + return tarinfo + subprocess.check_call(['dpkg-source', '--version'], stdout=subprocess.DEVNULL) + for area in areas: + urlbase = '{mirror}/dists/{dist}/{area}/'.format(mirror=mirror, dist=dist, area=area) + with Fetcher(urlbase=urlbase) as fetcher: + fetcher.add('Contents-source.gz', 'Contents.gz') + fetcher.add('source/Sources.xz', 'Sources.xz') + [contents_path, sources_path] = fetcher.run() + interesting_packages = set() + with gzip.open(contents_path, 'rt', encoding='UTF-8', newline='\n') as file: + for line in file: + try: + path, packages = line.rsplit('\t', 1) + except ValueError: + raise RuntimeError('malfomed line: {!r}'.format(line)) + if is_po_path(path): + packages = packages.rstrip('\n').split(',') + for pkg in packages: + validate_package_name(pkg) + interesting_packages.update(packages) + whole_size = 0 + for para in apt_pkg.TagFile(sources_path): + pkg = para['Package'] + if pkg not in interesting_packages: + continue + fileinfo = para['Files'].splitlines() + dscname = None + names = set() + for line in fileinfo: + _, size, _ = line.strip().split(' ') + size = int(size) + whole_size += size + progress = tqdm.tqdm(unit='B', unit_scale=True, bar_format='* {n_fmt}/{total_fmt}, {rate_fmt}, ETA: {remaining}\n') + progress.total = whole_size + progress.refresh() + for para in apt_pkg.TagFile(sources_path): + pkg = para['Package'] + if pkg not in interesting_packages: + continue + fileinfo = para['Files'].splitlines() + dscname = None + names = set() + size = 0 + for line in fileinfo: + _, fsize, name = line.strip().split(' ') + ok = ( + name.startswith(pkg + '_') and + '/' not in name and + name not in names + ) + if not ok: + raise RuntimeError('Package {pkg}: bad Files line: {line!r}'.format(pkg=pkg, line=line)) + names.add(name) + if name.endswith('.dsc'): + if dscname is not None: + raise RuntimeError('Package {pkg}: duplicate .dsc file'.format(pkg=pkg)) + dscname = name + size += int(fsize) + if dscname is None: + raise RuntimeError('Package {pkg}: missing .dsc file'.format(pkg=pkg)) + names = list(names) + names.sort(key=dscname.__eq__) + pkgdir = para['Directory'] + pkgurlbase = '{mirror}/{dir}/'.format(mirror=mirror, dir=pkgdir) + with Fetcher(urlbase=pkgurlbase) as pkgfetcher: + for name in names: + pkgfetcher.add(name, name) + for path in pkgfetcher.run(): + pass + dscpath = path + unpacked = dscpath[:-4] + subprocess.check_call(['dpkg-source', '-x', dscpath, unpacked], stdout=sys.stderr) + with chdir(os.path.dirname(unpacked)): + for unp_root, unp_dirs, unp_files in os.walk(os.path.basename(unpacked)): + try: + unp_dirs.remove('.pc') + except ValueError: + pass + for unp_file in unp_files: + if is_po_path(unp_file): + unp_path = os.path.join(unp_root, unp_file) + tar.add(unp_path, filter=tarfilter) + progress.update(size) + tar.close() + +if __name__ == '__main__': + main() + +# vim:ts=4 sts=4 sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/private/online-check-gettext-data new/i18nspector-0.25.4/private/online-check-gettext-data --- old/i18nspector-0.25.3/private/online-check-gettext-data 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/private/online-check-gettext-data 2017-06-23 18:25:45.000000000 +0200 @@ -33,11 +33,14 @@ # Remove superfluous parentheses around the plural formula: return re.sub(r'\bplural=\((.*?)\);$', r'plural=\1;', s) +def urlopen(url): + return urllib.request.urlopen(url, cadefault=True) + def do_plurals(): regexp = re.compile(r'\s+{\s*"([a-zA-Z_]+)".*"(nplurals.*?)"') url = 'http://git.savannah.gnu.org/cgit/gettext.git/plain/gettext-tools/src/plural-table.c' okay = set() - with urllib.request.urlopen(url) as file: + with urlopen(url) as file: for line in file: line = line.decode('ASCII').rstrip() match = regexp.match(line) @@ -51,7 +54,7 @@ print('[{}]'.format(language)) if our_plural_forms: if len(our_plural_forms) == 1: - print('# plural-forms =', our_plural_forms) + print('# plural-forms =', *our_plural_forms) else: print('# plural-forms =') for pf in our_plural_forms: @@ -72,7 +75,7 @@ def do_languages(): url = 'http://git.savannah.gnu.org/cgit/gettext.git/plain/gettext-tools/src/msginit.c' okay = set() - with urllib.request.urlopen(url) as file: + with urlopen(url) as file: contents = file.read() match = re.compile(br'locales_with_principal_territory\s*\[\]\s*=\s*[{](.*?)[}]', re.DOTALL).search(contents) if match is None: @@ -119,7 +122,7 @@ def do_string_formats(): url = 'http://git.savannah.gnu.org/cgit/gettext.git/plain/gettext-tools/src/message.c' - with urllib.request.urlopen(url) as file: + with urlopen(url) as file: contents = file.read() match = re.compile(br'\sformat_language\s*\[NFORMATS\]\s*=\s*[{](.*?)[}]', re.DOTALL).search(contents) if match is None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/private/run-pydiatra new/i18nspector-0.25.4/private/run-pydiatra --- old/i18nspector-0.25.3/private/run-pydiatra 1970-01-01 01:00:00.000000000 +0100 +++ new/i18nspector-0.25.4/private/run-pydiatra 2017-06-23 18:25:45.000000000 +0200 @@ -0,0 +1,32 @@ +#!/bin/sh + +# Copyright © 2016-2017 Jakub Wilk <jw...@jwilk.net> +# +# 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. + +PYTHON=${PYTHON:-python3} +if [ $# -eq 0 ] +then + set -- \ + $(grep -l -r '^#!.*python' .) \ + $(find . -name '*.py') +fi +exec "$PYTHON" -m pydiatra "$@" + +# vim:ts=4 sts=4 sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/private/run-pyflakes new/i18nspector-0.25.4/private/run-pyflakes --- old/i18nspector-0.25.3/private/run-pyflakes 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/private/run-pyflakes 2017-06-23 18:25:45.000000000 +0200 @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright © 2015-2016 Jakub Wilk <jw...@jwilk.net> +# Copyright © 2015-2017 Jakub Wilk <jw...@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -20,7 +20,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -pyflakes=$(which pyflakes) || { echo pyflakes not found >&2; exit 1; } -exec python3 "$pyflakes" "$@" $(grep -l -r --exclude='*.swp' '^#!.*python' .) $(find -name '*.py') +PYTHON=${PYTHON:-python3} +if [ $# -eq 0 ] +then + set -- \ + $(grep -l -r --exclude='*.swp' '^#!.*python' .) \ + $(find . -name '*.py') +fi +exec "$PYTHON" -m pyflakes "$@" # vim:ts=4 sts=4 sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/private/run-pylint new/i18nspector-0.25.4/private/run-pylint --- old/i18nspector-0.25.3/private/run-pylint 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/private/run-pylint 2017-06-23 18:25:45.000000000 +0200 @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright © 2015-2016 Jakub Wilk <jw...@jwilk.net> +# Copyright © 2015-2017 Jakub Wilk <jw...@jwilk.net> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the “Software”), to deal @@ -27,19 +27,31 @@ pyscripts=$(grep -l -r '^#!.*python' .) set -- lib tests tests/fuzzing/*/*.py $pyscripts fi -if "$PYTHON" -c 'import afl' 2>/dev/null +whitelist= +ignored= +for ext in afl apt_pkg +do + if "$PYTHON" -c "import $ext" 2>/dev/null + then + whitelist="$whitelist,$ext" + else + ignored="$ignored,$ext" + fi +done +if [ -z "${ignored%%*apt*}" ] then - set -- --extension-pkg-whitelist=afl "$@" -else - set -- --ignored-modules=afl "$@" + ignored="$ignored,apt" fi -! "$PYTHON" -m pylint "$@" \ -| grep '^\w:' \ +set -- --extension-pkg-whitelist="${whitelist#,}" --ignored-modules="${ignored#,}" "$@" +log=$(mktemp -t pylint.XXXXXX) +"$PYTHON" -m pylint "$@" > "$log" || [ $? != 1 ] +! grep '^\w:' "$log" \ | grep -v ': missing-docstring \[\w' \ | grep -v -P '^\w: (?!lib/).+: missing-docstring ' \ | grep -v ": redefined-builtin \\[.*\\] Redefining built-in 'input'" \ | grep -v -P "^\w: tests/.+: wrong-import-order \\[.*\\] external import \"import lib[.].+\" comes before \"from . import tools\"" \ | LC_ALL=C sort -k2 \ -| grep '.' +| grep '.' || exit 1 +rm "$log" # vim:ts=4 sts=4 sw=4 et diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/private/update-version new/i18nspector-0.25.4/private/update-version --- old/i18nspector-0.25.3/private/update-version 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/private/update-version 2017-06-23 18:25:45.000000000 +0200 @@ -2,5 +2,5 @@ version=${1:?"no version number provided"} set -e -x dch -m -v "$version" -u low -c doc/changelog -sed -i -r -e "s/(__version__) = '\S+'/\1 = '$version'/" lib/*.py -sed -i -r -e "s/^(:version: \S+) \S+$/\1 $version/" doc/*.txt +sed -i -E -e "s/(__version__) = '\S+'/\1 = '$version'/" lib/*.py +sed -i -E -e "s/^(:version: \S+) \S+$/\1 $version/" doc/*.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/tests/__init__.py new/i18nspector-0.25.4/tests/__init__.py --- old/i18nspector-0.25.3/tests/__init__.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/tests/__init__.py 2017-06-23 18:25:45.000000000 +0200 @@ -1,6 +1,2 @@ -import sys - -if sys.version_info < (3, 0): - raise ImportError('Python >= 3 is required') - -# vim:ts=4 sts=4 sw=4 et +# pylint: disable=pointless-statement +... # Python >= 3 is required diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/tests/blackbox_tests/__init__.py new/i18nspector-0.25.4/tests/blackbox_tests/__init__.py --- old/i18nspector-0.25.3/tests/blackbox_tests/__init__.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/tests/blackbox_tests/__init__.py 2017-06-23 18:25:45.000000000 +0200 @@ -226,10 +226,11 @@ for s in child.communicate() ) rc = child.poll() + assert isinstance(rc, int) if rc == 0: return stdout if rc < 0: - message = ['command was interrupted by signal {sig}'.format(sig=get_signal_name(-rc))] + message = ['command was interrupted by signal {sig}'.format(sig=get_signal_name(-rc))] # pylint: disable=invalid-unary-operand-type else: message = ['command exited with status {rc}'.format(rc=rc)] message += [''] @@ -273,9 +274,9 @@ stderr += ''.join( traceback.format_exception(exctp, exc, tb) ) - del tb queue.put([stdout, stderr]) sys.exit(1) + raise # hi, pydiatra! else: queue.put([stdout, stderr]) sys.exit(0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/tests/blackbox_tests/python-brace-format-string-argument-sorting.po new/i18nspector-0.25.4/tests/blackbox_tests/python-brace-format-string-argument-sorting.po --- old/i18nspector-0.25.3/tests/blackbox_tests/python-brace-format-string-argument-sorting.po 1970-01-01 01:00:00.000000000 +0100 +++ new/i18nspector-0.25.4/tests/blackbox_tests/python-brace-format-string-argument-sorting.po 2017-06-23 18:25:45.000000000 +0200 @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: Gizmo Enhancer 1.0\n" +"Report-Msgid-Bugs-To: gizmoenhan...@jwilk.net\n" +"POT-Creation-Date: 2012-11-01 14:42+0100\n" +"PO-Revision-Date: 2012-11-01 14:42+0100\n" +"Last-Translator: Jakub Wilk <jw...@jwilk.net>\n" +"Language-Team: Latin <l...@li.org>\n" +"Language: la\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#, python-brace-format +msgid "A quick brown {} jumps over the lazy {s}." +msgstr "Sic fugiens, {}, zelotypos, quam Karus {s}." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/tests/coverage.txt new/i18nspector-0.25.4/tests/coverage.txt --- old/i18nspector-0.25.3/tests/coverage.txt 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/tests/coverage.txt 2017-06-23 18:25:45.000000000 +0200 @@ -2,16 +2,16 @@ Name Stmts Miss Branch BrPart Cover Missing ---------------------------------------------------------------------------- -lib.py 0 0 0 0 100% +lib.py 1 0 0 0 100% lib/check.py 796 745 501 0 4% 81-85, 88-101, 109, 115-197, 200-216, 220-352, 356-500, 504-576, 580-618, 623-658, 663-707, 710-788, 791-871, 874-988, 991-998, 1001-1017, 1022 -lib/check/msgformat.py 84 71 36 0 11% 32, 36, 39, 42-152, 163, 167 +lib/check/msgformat.py 82 69 36 0 11% 32, 36, 39, 42-152 lib/check/msgformat/c.py 67 56 36 0 11% 37-44, 47-105, 108-129 -lib/check/msgformat/pybrace.py 32 24 13 0 18% 17-28, 31-53 +lib/check/msgformat/pybrace.py 34 26 13 0 17% 17-28, 31-55 lib/check/msgformat/python.py 77 67 47 0 8% 37-109, 112-149 lib/check/msgrepr.py 11 7 2 0 31% 28-34 lib/cli.py 156 122 44 0 17% 45-49, 58-67, 70-71, 74-76, 82-112, 115-120, 126-132, 135-143, 146-154, 160, 168-188, 191-225 lib/domains.py 15 0 0 0 100% -lib/encodings.py 130 38 34 1 73% 45, 50-68, 80-88, 187, 193, 201-213, 217-221, 185->187 +lib/encodings.py 127 36 34 1 73% 50-68, 80-88, 187, 201-213, 217-221, 185->187 lib/gettext.py 105 0 36 0 100% lib/iconv.py 161 56 54 18 59% 41-42, 55-57, 64, 66, 68, 70, 77-78, 87-88, 101-102, 115-127, 134-135, 138-149, 155, 157, 159, 161, 170-171, 184-185, 202-217, 226-227, 230-241, 63->64, 65->66, 67->68, 69->70, 76->77, 86->87, 100->101, 109->114, 114->115, 133->134, 154->155, 156->157, 158->159, 160->161, 169->170, 183->184, 199->202, 225->226 lib/intexpr.py 406 0 126 0 100% @@ -28,4 +28,4 @@ lib/terminal.py 55 24 4 0 53% 79-106 lib/xml.py 21 0 2 0 100% ---------------------------------------------------------------------------- -TOTAL 3444 1423 1509 30 55% +TOTAL 3442 1421 1509 30 55% diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/tests/test_encodings.py new/i18nspector-0.25.4/tests/test_encodings.py --- old/i18nspector-0.25.3/tests/test_encodings.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/tests/test_encodings.py 2017-06-23 18:25:45.000000000 +0200 @@ -21,6 +21,8 @@ import curses.ascii import sys +import lib.encodings as E + import nose from nose.tools import ( assert_equal, @@ -33,8 +35,6 @@ from . import tools -import lib.encodings as E - class test_is_portable_encoding: def test_found(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/tests/test_ling.py new/i18nspector-0.25.4/tests/test_ling.py --- old/i18nspector-0.25.3/tests/test_ling.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/tests/test_ling.py 2017-06-23 18:25:45.000000000 +0200 @@ -18,6 +18,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import lib.encodings +import lib.ling + import nose from nose.tools import ( assert_equal, @@ -34,9 +37,6 @@ from . import tools -import lib.encodings -import lib.ling - L = lib.ling T = lib.ling.Language E = lib.encodings @@ -79,8 +79,8 @@ def test_language_repr(): # Language.__repr__() is never used by i18nspector itself, # but it's useful for debugging test failures. - l = T('el') - assert_equal(repr(l), '<Language el>') + lng = T('el') + assert_equal(repr(lng), '<Language el>') class test_language_equality: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/tests/test_misc.py new/i18nspector-0.25.4/tests/test_misc.py --- old/i18nspector-0.25.3/tests/test_misc.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/tests/test_misc.py 2017-06-23 18:25:45.000000000 +0200 @@ -24,6 +24,8 @@ import tempfile import time +import lib.misc as M + from nose.tools import ( assert_almost_equal, assert_equal, @@ -35,8 +37,6 @@ from . import tools -import lib.misc as M - class test_unsorted: def t(self, lst, expected): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/tests/test_moparser.py new/i18nspector-0.25.4/tests/test_moparser.py --- old/i18nspector-0.25.3/tests/test_moparser.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/tests/test_moparser.py 2017-06-23 18:25:45.000000000 +0200 @@ -20,6 +20,8 @@ import random +import lib.moparser as M + from nose.tools import ( assert_equal, assert_raises, @@ -27,8 +29,6 @@ from . import tools -import lib.moparser as M - def parser_for_bytes(data): with tools.temporary_file(suffix='.mo') as file: file.write(data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/tests/test_polib4us.py new/i18nspector-0.25.4/tests/test_polib4us.py --- old/i18nspector-0.25.3/tests/test_polib4us.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/tests/test_polib4us.py 2017-06-23 18:25:45.000000000 +0200 @@ -20,6 +20,8 @@ import polib +import lib.polib4us as M + from nose.tools import ( assert_list_equal, assert_true, @@ -27,8 +29,6 @@ from . import tools -import lib.polib4us as M - minimal_header = r''' msgid "" msgstr "Content-Type: text/plain; charset=US-ASCII\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.3/tests/test_terminal.py new/i18nspector-0.25.4/tests/test_terminal.py --- old/i18nspector-0.25.3/tests/test_terminal.py 2016-08-29 13:25:44.000000000 +0200 +++ new/i18nspector-0.25.4/tests/test_terminal.py 2017-06-23 18:25:45.000000000 +0200 @@ -23,14 +23,14 @@ import pty import sys +import lib.terminal as T + from nose.tools import ( assert_equal, ) from . import tools -import lib.terminal as T - def test_strip_delay(): def t(s, r=b''): assert_equal(T._strip_delay(s), r) # pylint: disable=protected-access ++++++ i18nspector.keyring ++++++ --- /var/tmp/diff_new_pack.8jMH1k/_old 2017-08-18 15:06:40.978896123 +0200 +++ /var/tmp/diff_new_pack.8jMH1k/_new 2017-08-18 15:06:40.978896123 +0200 @@ -1,9 +1,9 @@ -pub rsa4096/015475F5 2009-10-23 [expires: 2017-01-01] -uid [ unknown] Jakub Wilk <jw...@jwilk.net> -uid [ unknown] Jakub Wilk <jw...@debian.org> -uid [ unknown] Jakub Wilk <uba...@users.sf.net> -uid [ unknown] [jpeg image of size 6044] -sub rsa4096/E5874F63 2009-10-23 +pub rsa4096 2009-10-23 [SC] [expires: 2018-01-01] + CDB5A1243ACDB63009AD07212D4EB3A6015475F5 +uid [ unknown] Jakub Wilk <jw...@jwilk.net> +uid [ full ] Jakub Wilk <jw...@debian.org> +uid [ full ] Jakub Wilk <uba...@users.sf.net> +sub rsa4096 2009-10-23 [E] -----BEGIN PGP PUBLIC KEY BLOCK----- @@ -18,66 +18,67 @@ 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 -I+6LSLcpBezT0Vb/6f0NPA== -=l89W +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 +i0i3KQXs09FW/+n9DTw= +=R8Zy -----END PGP PUBLIC KEY BLOCK-----