Hello community,
here is the log from the commit of package python-docformatter for
openSUSE:Factory checked in at 2019-07-26 17:34:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-docformatter (Old)
and /work/SRC/openSUSE:Factory/.python-docformatter.new.4126 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-docformatter"
Fri Jul 26 17:34:05 2019 rev:5 rq:718797 version:1.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-docformatter/python-docformatter.changes
2019-03-10 09:40:21.712104594 +0100
+++
/work/SRC/openSUSE:Factory/.python-docformatter.new.4126/python-docformatter.changes
2019-07-26 17:34:06.968092209 +0200
@@ -1,0 +2,6 @@
+Fri Jul 26 09:26:07 UTC 2019 - [email protected]
+
+- version update to 1.3
+ * no upstream changelog
+
+-------------------------------------------------------------------
Old:
----
docformatter-1.1.tar.gz
New:
----
docformatter-1.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-docformatter.spec ++++++
--- /var/tmp/diff_new_pack.C8Ufvd/_old 2019-07-26 17:34:07.944091824 +0200
+++ /var/tmp/diff_new_pack.C8Ufvd/_new 2019-07-26 17:34:07.948091822 +0200
@@ -18,7 +18,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-docformatter
-Version: 1.1
+Version: 1.3
Release: 0
Summary: Utility to re-format docstrings per PEP 257
License: MIT
@@ -31,6 +31,7 @@
# SECTION test requirements
BuildRequires: %{python_module untokenize}
# /SECTION
+Requires: python-setuptools
Requires: python-untokenize
BuildArch: noarch
@@ -72,6 +73,7 @@
%python_exec setup.py test
%files %{python_files}
+%license LICENSE
%doc AUTHORS.rst README.rst
%python3_only %{_bindir}/docformatter
%{python_sitelib}/*
++++++ docformatter-1.1.tar.gz -> docformatter-1.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/docformatter-1.1/AUTHORS.rst
new/docformatter-1.3/AUTHORS.rst
--- old/docformatter-1.1/AUTHORS.rst 2017-12-26 17:31:26.000000000 +0100
+++ new/docformatter-1.3/AUTHORS.rst 2019-07-17 15:23:07.000000000 +0200
@@ -9,3 +9,4 @@
- Manuel Kaufmann (https://github.com/humitos)
- Peter Boothe (https://github.com/pboothe)
- Kapshuna Alexander (https://github.com/kapsh)
+- Serhiy Yevtushenko (https://github.com/serhiy-yevtushenko)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/docformatter-1.1/PKG-INFO
new/docformatter-1.3/PKG-INFO
--- old/docformatter-1.1/PKG-INFO 2019-03-02 18:02:17.000000000 +0100
+++ new/docformatter-1.3/PKG-INFO 2019-07-17 15:32:48.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: docformatter
-Version: 1.1
+Version: 1.3
Summary: Formats docstrings to follow PEP 257.
Home-page: https://github.com/myint/docformatter
Author: Steven Myint
@@ -139,7 +139,7 @@
Below is the help output::
- usage: docformatter [-h] [-i] [-r] [--wrap-summaries length]
+ usage: docformatter [-h] [-i | -c] [-r] [--wrap-summaries length]
[--wrap-descriptions length] [--blank]
[--pre-summary-newline]
[--make-summary-multi-line]
[--force-wrap] [--range line line] [--version]
@@ -153,6 +153,7 @@
optional arguments:
-h, --help show this help message and exit
-i, --in-place make changes to files instead of printing
diffs
+ -c, --check only check and report incorrectly
formatted files
-r, --recursive drill down directories recursively
--wrap-summaries length
wrap long summary lines at this length;
set to 0 to
@@ -174,6 +175,11 @@
--version show program's version number and exit
+ Possible exit codes:
+
+ - **1** - if any error encountered
+ - **3** - if any file needs to be formatted (in ``--check`` mode)
+
Wrapping descriptions
=====================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/docformatter-1.1/README.rst
new/docformatter-1.3/README.rst
--- old/docformatter-1.1/README.rst 2018-01-05 17:54:23.000000000 +0100
+++ new/docformatter-1.3/README.rst 2019-05-24 19:17:04.000000000 +0200
@@ -131,7 +131,7 @@
Below is the help output::
- usage: docformatter [-h] [-i] [-r] [--wrap-summaries length]
+ usage: docformatter [-h] [-i | -c] [-r] [--wrap-summaries length]
[--wrap-descriptions length] [--blank]
[--pre-summary-newline] [--make-summary-multi-line]
[--force-wrap] [--range line line] [--version]
@@ -145,6 +145,7 @@
optional arguments:
-h, --help show this help message and exit
-i, --in-place make changes to files instead of printing diffs
+ -c, --check only check and report incorrectly formatted files
-r, --recursive drill down directories recursively
--wrap-summaries length
wrap long summary lines at this length; set to 0 to
@@ -166,6 +167,11 @@
--version show program's version number and exit
+Possible exit codes:
+
+- **1** - if any error encountered
+- **3** - if any file needs to be formatted (in ``--check`` mode)
+
Wrapping descriptions
=====================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/docformatter-1.1/docformatter.egg-info/PKG-INFO
new/docformatter-1.3/docformatter.egg-info/PKG-INFO
--- old/docformatter-1.1/docformatter.egg-info/PKG-INFO 2019-03-02
18:02:17.000000000 +0100
+++ new/docformatter-1.3/docformatter.egg-info/PKG-INFO 2019-07-17
15:32:47.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: docformatter
-Version: 1.1
+Version: 1.3
Summary: Formats docstrings to follow PEP 257.
Home-page: https://github.com/myint/docformatter
Author: Steven Myint
@@ -139,7 +139,7 @@
Below is the help output::
- usage: docformatter [-h] [-i] [-r] [--wrap-summaries length]
+ usage: docformatter [-h] [-i | -c] [-r] [--wrap-summaries length]
[--wrap-descriptions length] [--blank]
[--pre-summary-newline]
[--make-summary-multi-line]
[--force-wrap] [--range line line] [--version]
@@ -153,6 +153,7 @@
optional arguments:
-h, --help show this help message and exit
-i, --in-place make changes to files instead of printing
diffs
+ -c, --check only check and report incorrectly
formatted files
-r, --recursive drill down directories recursively
--wrap-summaries length
wrap long summary lines at this length;
set to 0 to
@@ -174,6 +175,11 @@
--version show program's version number and exit
+ Possible exit codes:
+
+ - **1** - if any error encountered
+ - **3** - if any file needs to be formatted (in ``--check`` mode)
+
Wrapping descriptions
=====================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/docformatter-1.1/docformatter.py
new/docformatter-1.3/docformatter.py
--- old/docformatter-1.1/docformatter.py 2019-03-02 18:01:48.000000000
+0100
+++ new/docformatter-1.3/docformatter.py 2019-07-17 15:23:41.000000000
+0200
@@ -29,6 +29,7 @@
print_function,
unicode_literals)
+import collections
import io
import locale
import os
@@ -41,7 +42,7 @@
import untokenize
-__version__ = '1.1'
+__version__ = '1.3'
try:
@@ -52,6 +53,19 @@
HEURISTIC_MIN_LIST_ASPECT_RATIO = .4
+CR = '\r'
+LF = '\n'
+CRLF = '\r\n'
+
+
+class FormatResult(object):
+ """Possible exit codes."""
+
+ ok = 0
+ error = 1
+ interrupted = 2
+ check_failed = 3
+
def format_code(source, **kwargs):
"""Return source code with docstrings formatted.
@@ -61,7 +75,10 @@
See "_format_code()" for parameters.
"""
try:
- return _format_code(source, **kwargs)
+ original_newline = find_newline(source.splitlines(True))
+ code = _format_code(source, **kwargs)
+
+ return normalize_line_endings(code.splitlines(True), original_newline)
except (tokenize.TokenError, IndentationError):
return source
@@ -372,6 +389,43 @@
return indentation or ''
+def find_newline(source):
+ """Return type of newline used in source.
+
+ Input is a list of lines.
+ """
+ assert not isinstance(source, unicode)
+
+ counter = collections.defaultdict(int)
+ for line in source:
+ if line.endswith(CRLF):
+ counter[CRLF] += 1
+ elif line.endswith(CR):
+ counter[CR] += 1
+ elif line.endswith(LF):
+ counter[LF] += 1
+ return (sorted(counter, key=counter.get, reverse=True) or [LF])[0]
+
+
+def normalize_line(line, newline):
+ """Return line with fixed ending, if ending was present in line.
+
+ Otherwise, does nothing.
+ """
+ stripped = line.rstrip('\n\r')
+ if stripped != line:
+ return stripped + newline
+ return line
+
+
+def normalize_line_endings(lines, newline):
+ """Return fixed line endings.
+
+ All lines will be modified to use the most common line ending.
+ """
+ return ''.join([normalize_line(line, newline) for line in lines])
+
+
def strip_docstring(docstring):
"""Return contents of docstring."""
docstring = docstring.strip()
@@ -496,14 +550,19 @@
def format_file(filename, args, standard_out):
- """Run format_code() on a file."""
+ """Run format_code() on a file.
+
+ Return: one of the FormatResult codes.
+ """
encoding = detect_encoding(filename)
with open_with_encoding(filename, encoding=encoding) as input_file:
source = input_file.read()
formatted_source = _format_code_with_args(source, args)
if source != formatted_source:
- if args.in_place:
+ if args.check:
+ return FormatResult.check_failed
+ elif args.in_place:
with open_with_encoding(filename, mode='w',
encoding=encoding) as output_file:
output_file.write(formatted_source)
@@ -517,6 +576,8 @@
lineterm='')
standard_out.write('\n'.join(list(diff) + ['']))
+ return FormatResult.ok
+
def _format_code_with_args(source, args):
"""Run format_code with parsed command-line arguments."""
@@ -535,8 +596,13 @@
"""Run internal main entry point."""
import argparse
parser = argparse.ArgumentParser(description=__doc__, prog='docformatter')
- parser.add_argument('-i', '--in-place', action='store_true',
- help='make changes to files instead of printing diffs')
+ changes = parser.add_mutually_exclusive_group()
+ changes.add_argument('-i', '--in-place', action='store_true',
+ help='make changes to files instead of printing '
+ 'diffs')
+ changes.add_argument('-c', '--check', action='store_true',
+ help='only check and report incorrectly formatted '
+ 'files')
parser.add_argument('-r', '--recursive', action='store_true',
help='drill down directories recursively')
parser.add_argument('--wrap-summaries', default=79, type=int,
@@ -587,9 +653,9 @@
standard_out=standard_out,
standard_in=standard_in)
else:
- _format_files(args,
- standard_out=standard_out,
- standard_error=standard_error)
+ return _format_files(args,
+ standard_out=standard_out,
+ standard_error=standard_error)
def _format_standard_in(args, parser, standard_out, standard_in):
@@ -625,7 +691,7 @@
def find_py_files(sources, recursive):
"""Find Python source files.
- Parameters:
+ Parameters
- sources: iterable with paths as strings.
- recursive: drill down directories if True.
@@ -647,13 +713,31 @@
def _format_files(args, standard_out, standard_error):
- """Format multiple files."""
+ """Format multiple files.
+
+ Return: one of the FormatResult codes.
+ """
+ outcomes = collections.Counter()
for filename in find_py_files(set(args.files), args.recursive):
try:
- format_file(filename, args=args, standard_out=standard_out)
+ result = format_file(filename, args=args,
+ standard_out=standard_out)
+ outcomes[result] += 1
+ if result == FormatResult.check_failed:
+ print(unicode(filename), file=standard_error)
except IOError as exception:
+ outcomes[FormatResult.error] += 1
print(unicode(exception), file=standard_error)
+ return_codes = [ # in order of preference
+ FormatResult.error,
+ FormatResult.check_failed,
+ FormatResult.ok,
+ ]
+ for code in return_codes:
+ if outcomes[code]:
+ return code
+
def main():
"""Run main entry point."""
@@ -670,7 +754,7 @@
standard_error=sys.stderr,
standard_in=sys.stdin)
except KeyboardInterrupt:
- return 2 # pragma: no cover
+ return FormatResult.interrupted # pragma: no cover
if __name__ == '__main__':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/docformatter-1.1/test_docformatter.py
new/docformatter-1.3/test_docformatter.py
--- old/docformatter-1.1/test_docformatter.py 2019-02-09 19:42:35.000000000
+0100
+++ new/docformatter-1.3/test_docformatter.py 2019-07-17 15:10:43.000000000
+0200
@@ -822,6 +822,57 @@
self.assertEqual('"""\n',
docformatter.format_code('"""\n'))
+ def test_format_code_with_syntax_error_case_slash_r(self):
+ self.assertEqual('"""\r',
+ docformatter.format_code('"""\r'))
+
+ def test_format_code_with_syntax_error_case_slash_r_slash_n(self):
+ self.assertEqual('"""\r\n',
+ docformatter.format_code('"""\r\n'))
+
+ def test_find_newline_only_cr(self):
+ source = ['print 1\r', 'print 2\r', 'print3\r']
+ self.assertEqual(docformatter.CR, docformatter.find_newline(source))
+
+ def test_find_newline_only_lf(self):
+ source = ['print 1\n', 'print 2\n', 'print3\n']
+ self.assertEqual(docformatter.LF, docformatter.find_newline(source))
+
+ def test_find_newline_only_crlf(self):
+ source = ['print 1\r\n', 'print 2\r\n', 'print3\r\n']
+ self.assertEqual(docformatter.CRLF, docformatter.find_newline(source))
+
+ def test_find_newline_cr1_and_lf2(self):
+ source = ['print 1\n', 'print 2\r', 'print3\n']
+ self.assertEqual(docformatter.LF, docformatter.find_newline(source))
+
+ def test_find_newline_cr1_and_crlf2(self):
+ source = ['print 1\r\n', 'print 2\r', 'print3\r\n']
+ self.assertEqual(docformatter.CRLF, docformatter.find_newline(source))
+
+ def test_find_newline_should_default_to_lf(self):
+ self.assertEqual(docformatter.LF, docformatter.find_newline([]))
+ self.assertEqual(docformatter.LF, docformatter.find_newline(['', '']))
+
+ def test_format_code_dominant_line_ending_style_preserved(self):
+ input = '''\
+def foo():\r
+ """\r
+ Hello\r
+ foo. This is a docstring.\r
+ """\r
+'''
+ self.assertEqual(docformatter.CRLF,
docformatter.find_newline(input.splitlines(True)))
+ self.assertEqual(
+ '''\
+def foo():\r
+ """Hello foo.\r
+\r
+ This is a docstring.\r
+ """\r
+''',
+ docformatter.format_code(input))
+
def test_split_summary_and_description(self):
self.assertEqual(
('This is the first.',
@@ -1323,6 +1374,46 @@
self.assertIn('cannot be used',
process.communicate()[1].decode())
+ def test_io_error_exit_code(self):
+ stderr = io.StringIO()
+ ret_code = docformatter._main(
+ argv=['my_fake_program', 'this_file_should_not_exist_please'],
+ standard_out=None, standard_error=stderr, standard_in=None)
+ self.assertEqual(ret_code, 1)
+
+ def test_check_mode_correct_docstring(self):
+ with temporary_file('''
+"""Totally fine docstring, do not report anything."""
+''') as filename:
+ stdout = io.StringIO()
+ stderr = io.StringIO()
+ ret_code = docformatter._main(
+ argv=['my_fake_program', '--check', filename],
+ standard_out=stdout, standard_error=stderr, standard_in=None)
+ self.assertEqual(ret_code, 0,
+ msg='Exit code should be 0') # FormatResult.ok
+ self.assertEqual(stdout.getvalue(), '',
+ msg='Do not write to stdout')
+ self.assertEqual(stderr.getvalue(), '',
+ msg='Do not write to stderr')
+
+ def test_check_mode_incorrect_docstring(self):
+ with temporary_file('''
+"""
+Print my path and return error code
+""" ''') as filename:
+ stdout = io.StringIO()
+ stderr = io.StringIO()
+ ret_code = docformatter._main(
+ argv=['my_fake_program', '--check', filename],
+ standard_out=stdout, standard_error=stderr, standard_in=None)
+ self.assertEqual(ret_code, 3,
+ msg='Exit code should be 3') #
FormatResult.check_failed
+ self.assertEqual(stdout.getvalue(), '',
+ msg='Do not write to stdout')
+ self.assertEqual(stderr.getvalue().strip(), filename,
+ msg='Changed file should be reported')
+
def generate_random_docstring(max_indentation_length=32,
max_word_length=20,