Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-blue for openSUSE:Factory checked in at 2022-01-21 01:25:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-blue (Old) and /work/SRC/openSUSE:Factory/.python-blue.new.1938 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-blue" Fri Jan 21 01:25:26 2022 rev:3 rq:945752 version:0.7.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-blue/python-blue.changes 2021-03-17 20:20:00.255321565 +0100 +++ /work/SRC/openSUSE:Factory/.python-blue.new.1938/python-blue.changes 2022-01-21 01:25:56.438373108 +0100 @@ -1,0 +2,8 @@ +Wed Jan 12 07:25:55 UTC 2022 - Steve Kowalik <steven.kowa...@suse.com> + +- Update to 0.7.0: + * Upgrade dependency on black to 21.7b0 +- Add patch support-new-flake8.patch: + * Support backwards incompatiable changes with flake8 4.0 + +------------------------------------------------------------------- Old: ---- blue-0.6.0.tar.gz New: ---- blue-0.7.0.tar.gz support-new-flake8.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-blue.spec ++++++ --- /var/tmp/diff_new_pack.FedFCy/_old 2022-01-21 01:25:57.022369105 +0100 +++ /var/tmp/diff_new_pack.FedFCy/_new 2022-01-21 01:25:57.026369077 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-blue # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,15 +20,16 @@ %define skip_python2 1 %define modname blue Name: python-blue -Version: 0.6.0 +Version: 0.7.0 Release: 0 Summary: A code formatter written in, and written for Python License: MIT URL: https://github.com/grantjenks/blue Source: https://github.com/grantjenks/%{modname}/archive/v%{version}.tar.gz#/%{modname}-%{version}.tar.gz +Patch0: support-new-flake8.patch BuildRequires: %{python_module Sphinx} BuildRequires: %{python_module base >= 3.6} -BuildRequires: %{python_module black} +BuildRequires: %{python_module black >= 21.7} # BuildRequires: %%{python_module doc8} BuildRequires: %{python_module flake8} BuildRequires: %{python_module pytest-cov} @@ -45,7 +46,7 @@ Requires: python-aiohttp_cors Requires: python-appdirs Requires: python-attrs >= 18.1.0 -Requires: python-black +Requires: python-black >= 21.7 Requires: python-click >= 7.1.2 Requires: python-flake8 Requires: python-mypy_extensions >= 0.4.3 @@ -81,7 +82,7 @@ HTML Documentation and examples for %name. %prep -%setup -q -n blue-%{version} +%autosetup -p1 -n blue-%{version} %build %python_build ++++++ blue-0.6.0.tar.gz -> blue-0.7.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/.github/workflows/integration.yml new/blue-0.7.0/.github/workflows/integration.yml --- old/blue-0.6.0/.github/workflows/integration.yml 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/.github/workflows/integration.yml 2021-08-17 05:09:01.000000000 +0200 @@ -31,7 +31,7 @@ strategy: max-parallel: 8 matrix: - os: [ubuntu-latest, macos-latest, windows-latest, ubuntu-16.04] + os: [ubuntu-latest, macos-latest, windows-latest, ubuntu-18.04] python-version: [3.6, 3.7, 3.8, 3.9] steps: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/.gitignore new/blue-0.7.0/.gitignore --- old/blue-0.6.0/.gitignore 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/.gitignore 2021-08-17 05:09:01.000000000 +0200 @@ -6,7 +6,7 @@ # test files/directories /.cache/ -.coverage +.coverage* .pytest_cache/ /.tox/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/.pre-commit-hooks.yaml new/blue-0.7.0/.pre-commit-hooks.yaml --- old/blue-0.6.0/.pre-commit-hooks.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/blue-0.7.0/.pre-commit-hooks.yaml 2021-08-17 05:09:01.000000000 +0200 @@ -0,0 +1,9 @@ +- id: blue + name: blue + description: "Blue: The somewhat less uncompromising Python code formatter" + entry: blue + language: python + language_version: python3 + minimum_pre_commit_version: 2.9.2 + require_serial: true + types_or: [python, pyi] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/README.rst new/blue-0.7.0/README.rst --- old/blue-0.6.0/README.rst 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/README.rst 2021-08-17 05:09:01.000000000 +0200 @@ -46,10 +46,11 @@ * ``blue`` defaults to single-quoted strings. This is probably the most painful ``black`` choice to our eyes, and the thing that inspired ``blue``. - We strongly prefer using single quoted strings over double quoted strings - for everything *except* docstrings. Don't ask us why we prefer double - quoted strings for docstrings; it just looks better to us! For all other - strings, ``blue`` defaults to single quoted strings. + We strongly prefer using single quoted strings over double quoted strings for + everything *except* docstrings and triple quoted strings (TQS). Don't ask us + why we prefer double-quotes for TQS; it just looks better to us! For all + other strings, ``blue`` defaults to single quoted strings. In the case of + docstrings, those always use TQS with double-quotes. * ``blue`` defaults to line lengths of 79 characters. Nearly every project creates a pyproject.toml just to change this one setting so making it diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/blue/__init__.py new/blue-0.7.0/blue/__init__.py --- old/blue-0.6.0/blue/__init__.py 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/blue/__init__.py 2021-08-17 05:09:01.000000000 +0200 @@ -1,7 +1,6 @@ """Blue Some folks like black but I prefer blue. - """ import logging @@ -9,41 +8,49 @@ import sys import black - -from black import ( - Leaf, - Path, - ProtoComment, +import black.cache +import black.comments +import black.strings + +from black import Leaf, Path, click, token +from black.cache import user_cache_dir +from black.comments import ProtoComment, make_comment +from black.files import tomli +from black.linegen import LineGenerator as BlackLineGenerator +from black.lines import Line +from black.nodes import ( STANDALONE_COMMENT, - STRING_PREFIX_CHARS, - click, - make_comment, + is_multiline_string, prev_siblings_are, - sub_twice, syms, - token, - toml, - user_cache_dir, ) +from black.strings import ( + STRING_PREFIX_CHARS, + get_string_prefix, + normalize_string_prefix, + sub_twice, +) + from flake8.options import config as flake8_config from flake8.options import manager as flake8_manager from enum import Enum from functools import lru_cache -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Iterator, List, Optional from click.decorators import version_option -__version__ = '0.6.0' +__version__ = '0.7.0' LOG = logging.getLogger(__name__) -black_normalize_string_quotes = black.normalize_string_quotes black_format_file_in_place = black.format_file_in_place +black_strings_fix_docstring = black.strings.fix_docstring +black_strings_normalize_string_quotes = black.strings.normalize_string_quotes # Try not to poison Black's cache directory. -black.CACHE_DIR = Path(user_cache_dir('blue', version=__version__)) +black.cache.CACHE_DIR = Path(user_cache_dir('blue', version=__version__)) # Blue works by monkey patching black, so we don't have to duplicate @@ -68,20 +75,30 @@ BLUE_MONKEYPATCHES = [ # Synchronous Monkees. - ('format_file_in_place', Mode.synchronous), - ('normalize_string_quotes', Mode.synchronous), - ('parse_pyproject_toml', Mode.synchronous), + (black, 'format_file_in_place', Mode.synchronous), + (black, 'parse_pyproject_toml', Mode.synchronous), + (black, 'LineGenerator', Mode.synchronous), + (black.files, 'parse_pyproject_toml', Mode.synchronous), + (black.linegen, 'normalize_string_quotes', Mode.synchronous), + (black.strings, 'normalize_string_quotes', Mode.synchronous), + (black.trans, 'normalize_string_quotes', Mode.synchronous), + (black.comments, 'list_comments', Mode.synchronous), + (black.linegen, 'list_comments', Mode.synchronous), # Asynchronous Monkees. - ('normalize_string_quotes', Mode.asynchronous), - ('list_comments', Mode.asynchronous), + (black, 'LineGenerator', Mode.asynchronous), + (black.linegen, 'normalize_string_quotes', Mode.asynchronous), + (black.strings, 'normalize_string_quotes', Mode.asynchronous), + (black.trans, 'normalize_string_quotes', Mode.asynchronous), + (black.comments, 'list_comments', Mode.asynchronous), + (black.linegen, 'list_comments', Mode.asynchronous), ] def monkey_patch_black(mode: Mode) -> None: blue = sys.modules['blue'] - for function_name, monkey_mode in BLUE_MONKEYPATCHES: + for module, function_name, monkey_mode in BLUE_MONKEYPATCHES: if monkey_mode is mode: - setattr(black, function_name, getattr(blue, function_name)) + setattr(module, function_name, getattr(blue, function_name)) # Because blue makes different choices than black, and all of this code is @@ -91,19 +108,15 @@ # fmt: off def is_docstring(leaf: Leaf) -> bool: - # Most of this function was copied from Black! - if prev_siblings_are( leaf.parent, [None, token.NEWLINE, token.INDENT, syms.simple_stmt] ): return True # Multiline docstring on the same line as the `def`. - if prev_siblings_are( - leaf.parent, [syms.parameters, token.COLON, syms.simple_stmt] - ): - # `syms.parameters` is only used in funcdefs and async_funcdefs in the - # Python grammar. We're safe to return True without further checks. + if prev_siblings_are(leaf.parent, [syms.parameters, token.COLON, syms.simple_stmt]): + # `syms.parameters` is only used in funcdefs and async_funcdefs in the Python + # grammar. We're safe to return True without further checks. return True if leaf.parent.prev_sibling is None and leaf.column == 0: @@ -113,48 +126,39 @@ return False -def normalize_string_quotes(leaf: Leaf) -> None: +def normalize_string_quotes(s: str) -> str: """Prefer *single* quotes but only if it doesn't cause more escaping. Adds or removes backslashes as appropriate. Doesn't parse and fix - strings nested in f-strings (yet). - - Note: Mutates its argument. + strings nested in f-strings. """ - if is_docstring(leaf): - black_normalize_string_quotes(leaf) - return - - # The remainder of this function is copied from black but double quotes are - # swapped with single quotes in all places. - - value = leaf.value.lstrip(STRING_PREFIX_CHARS) - if value[:3] == "'''": - return - - elif value[:3] == '"""': - orig_quote = '"""' - new_quote = "'''" + value = s.lstrip(STRING_PREFIX_CHARS) + if value[:3] == '"""': + return s + + elif value[:3] == "'''": + orig_quote = "'''" + new_quote = '"""' elif value[0] == "'": orig_quote = "'" new_quote = '"' else: orig_quote = '"' new_quote = "'" - first_quote_pos = leaf.value.find(orig_quote) + first_quote_pos = s.find(orig_quote) if first_quote_pos == -1: - return # There's an internal error + return s # There's an internal error - prefix = leaf.value[:first_quote_pos] + prefix = s[:first_quote_pos] unescaped_new_quote = re.compile(rf'(([^\\]|^)(\\\\)*){new_quote}') escaped_new_quote = re.compile(rf'([^\\]|^)\\((?:\\\\)*){new_quote}') escaped_orig_quote = re.compile(rf'([^\\]|^)\\((?:\\\\)*){orig_quote}') - body = leaf.value[first_quote_pos + len(orig_quote) : -len(orig_quote)] + body = s[first_quote_pos + len(orig_quote) : -len(orig_quote)] if 'r' in prefix.casefold(): if unescaped_new_quote.search(body): # There's at least one unescaped new_quote in this raw string # so converting is impossible - return + return s # Do not introduce or remove backslashes in raw strings new_body = body @@ -164,27 +168,23 @@ if body != new_body: # Consider the string without unnecessary escapes as the original body = new_body - leaf.value = f'{prefix}{orig_quote}{body}{orig_quote}' - new_body = sub_twice( - escaped_orig_quote, rf'\1\2{orig_quote}', new_body - ) - new_body = sub_twice( - unescaped_new_quote, rf'\1\\{new_quote}', new_body - ) + s = f'{prefix}{orig_quote}{body}{orig_quote}' + new_body = sub_twice(escaped_orig_quote, rf'\1\2{orig_quote}', new_body) + new_body = sub_twice(unescaped_new_quote, rf'\1\\{new_quote}', new_body) if 'f' in prefix.casefold(): matches = re.findall( - r''' - (?:[^{]|^)\{ # start of the str or a non-{ followed by a single { + r""" + (?:[^{]|^)\{ # start of the string or a non-{ followed by a single { ([^{].*?) # contents of the brackets except if begins with {{ - \}(?:[^}]|$) # A } followed by end of the string or a non-} - ''', + \}(?:[^}]|$) # A } followed by end of the string or a non-} + """, new_body, re.VERBOSE, ) for m in matches: if '\\' in str(m): # Do not introduce backslashes in interpolated expressions - return + return s if new_quote == "'''" and new_body[-1:] == "'": # edge case: @@ -192,19 +192,12 @@ orig_escape_count = body.count('\\') new_escape_count = new_body.count('\\') if new_escape_count > orig_escape_count: - return # Do not introduce more escaping + return s # Do not introduce more escaping if new_escape_count == orig_escape_count and orig_quote == "'": - return # Prefer single quotes + return s # Prefer double quotes - leaf.value = f'{prefix}{new_quote}{new_body}{new_quote}' - - -def format_file_in_place(*args, **kws): - # This is a convenient place to monkey patch any function that must be - # done after black's asynchronous invocation. - monkey_patch_black(Mode.asynchronous) - return black_format_file_in_place(*args, **kws) + return f'{prefix}{new_quote}{new_body}{new_quote}' # Like black's list_comments() but preserves whitespace leading up to the hash @@ -214,6 +207,7 @@ # https://github.com/grantjenks/blue/issues/14 @lru_cache(maxsize=4096) def list_comments(prefix: str, *, is_endmarker: bool) -> List[ProtoComment]: + """Return a list of :class:`ProtoComment` objects parsed from the given `prefix`.""" result: List[ProtoComment] = [] if not prefix or "#" not in prefix: return result @@ -267,15 +261,77 @@ def parse_pyproject_toml(path_config: str) -> Dict[str, Any]: """Parse a pyproject toml file, pulling out relevant parts for Black - If parsing fails, will raise a toml.TomlDecodeError + If parsing fails, will raise a tomli.TOMLDecodeError """ - pyproject_toml = toml.load(path_config) - # Read the "blue" section of pyproject.toml for configs. + with open(path_config, encoding="utf8") as f: + pyproject_toml = tomli.load(f) # type: ignore # due to deprecated API usage config = pyproject_toml.get("tool", {}).get("blue", {}) - return {k.replace("--", "").replace("-", "_"): v for k, v in config.items()} # noqa: E501 + return {k.replace("--", "").replace("-", "_"): v for k, v in config.items()} + + +def fix_docstring(docstring: str, prefix: str) -> str: + new_docstring = black_strings_fix_docstring(docstring, prefix) + # Needs special handling for module docstring case! + if docstring.endswith('\n') and not new_docstring.endswith('\n'): + new_docstring += '\n' + return new_docstring + + +class LineGenerator(BlackLineGenerator): + + def visit_STRING(self, leaf: Leaf) -> Iterator[Line]: + if is_docstring(leaf) and "\\\n" not in leaf.value: + # We're ignoring docstrings with backslash newline escapes because changing + # indentation of those changes the AST representation of the code. + docstring = normalize_string_prefix(leaf.value, self.remove_u_prefix) + prefix = get_string_prefix(docstring) + docstring = docstring[len(prefix) :] # Remove the prefix + quote_char = docstring[0] + # A natural way to remove the outer quotes is to do: + # docstring = docstring.strip(quote_char) + # but that breaks on """""x""" (which is '""x'). + # So we actually need to remove the first character and the next two + # characters but only if they are the same as the first. + quote_len = 1 if docstring[1] != quote_char else 3 + docstring = docstring[quote_len:-quote_len] + docstring_started_empty = not docstring + + if is_multiline_string(leaf): + indent = " " * 4 * self.current_line.depth + docstring = fix_docstring(docstring, indent) + else: + docstring = docstring.strip() + + if docstring: + # Add some padding if the docstring starts / ends with a quote mark. + if docstring[0] == quote_char: + docstring = " " + docstring + if docstring[-1] == quote_char: + docstring += " " + if docstring[-1] == "\\": + backslash_count = len(docstring) - len(docstring.rstrip("\\")) + if backslash_count % 2: + # Odd number of tailing backslashes, add some padding to + # avoid escaping the closing string quote. + docstring += " " + elif not docstring_started_empty: + docstring = " " + + # Enforce triple double quotes at this point. + quote = '"""' + leaf.value = prefix + quote + docstring + quote + + yield from self.visit_default(leaf) # fmt: on +def format_file_in_place(*args, **kws): + # This is a convenient place to monkey patch any function that must be + # done after black's asynchronous invocation. + monkey_patch_black(Mode.asynchronous) + return black_format_file_in_place(*args, **kws) + + class MergedConfigParser(flake8_config.MergedConfigParser): def _parse_config(self, config_parser, parent=None): """Skip option parsing in flake8's config parsing.""" @@ -325,7 +381,7 @@ 'Black', 'Blue' ) # Change the config param callback to support setup.cfg, tox.ini, etc. - config_param = black.main.params[17] + config_param = black.main.params[21] assert config_param.name == 'config' config_param.callback = read_configs # Change the version string by adding a redundant Click `version_option` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/docs/index.rst new/blue-0.7.0/docs/index.rst --- old/blue-0.6.0/docs/index.rst 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/docs/index.rst 2021-08-17 05:09:01.000000000 +0200 @@ -5,6 +5,15 @@ ======= +2021-08-16 (0.7.0) +------------------ + +- Bump dependency on Black to 21.7b0 +- Prefer double quotes for non-docstring triple quoted strings (GH#10) +- Add support for "py39" as target-version (GH#44) +- Docstrings now always use triple-double-quoted strings (GH#5) + + 2021-02-11 (0.6.0) ------------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/docs/requirements.txt new/blue-0.7.0/docs/requirements.txt --- old/blue-0.6.0/docs/requirements.txt 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/docs/requirements.txt 2021-08-17 05:09:01.000000000 +0200 @@ -1,2 +1,2 @@ -black==20.8b1 +black==21.7b0 flake8==3.8.4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/setup.py new/blue-0.7.0/setup.py --- old/blue-0.6.0/setup.py 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/setup.py 2021-08-17 05:09:01.000000000 +0200 @@ -37,7 +37,7 @@ packages=['blue'], tests_require=['tox'], cmdclass={'test': Tox}, - install_requires=['black==20.8b1', 'flake8==3.8.4'], + install_requires=['black==21.7b0', 'flake8==3.8.4'], project_urls={ 'Documentation': 'https://blue.readthedocs.io/en/latest', 'Source': 'https://github.com/grantjenks/blue.git', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/tests/bad_cases/demo.py new/blue-0.7.0/tests/bad_cases/demo.py --- old/blue-0.6.0/tests/bad_cases/demo.py 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/tests/bad_cases/demo.py 2021-08-17 05:09:01.000000000 +0200 @@ -1,5 +1,4 @@ # Copied from the Black Playground at https://black.now.sh/ (MIT LICENSE) -# And reformated with Blue :) from seven_dwwarfs import Grumpy, Happy, Sleepy, Bashful, Sneezy, Dopey, Doc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/tests/bad_cases/sdq_docstrings.py new/blue-0.7.0/tests/bad_cases/sdq_docstrings.py --- old/blue-0.6.0/tests/bad_cases/sdq_docstrings.py 1970-01-01 01:00:00.000000000 +0100 +++ new/blue-0.7.0/tests/bad_cases/sdq_docstrings.py 2021-08-17 05:09:01.000000000 +0200 @@ -0,0 +1,12 @@ +"This is a module docstring." +# Test single-double-quotes docstrings. + + +class Test: + "This is a class docstring." + pass + + +def test(): + "This is a func docstring." + pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/tests/bad_cases/ssq_docstrings.py new/blue-0.7.0/tests/bad_cases/ssq_docstrings.py --- old/blue-0.6.0/tests/bad_cases/ssq_docstrings.py 1970-01-01 01:00:00.000000000 +0100 +++ new/blue-0.7.0/tests/bad_cases/ssq_docstrings.py 2021-08-17 05:09:01.000000000 +0200 @@ -0,0 +1,12 @@ +'This is a module docstring.' +# Test single-single-quotes docstrings. + + +class Test: + 'This is a class docstring.' + pass + + +def test(): + 'This is a func docstring.' + pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/tests/bad_cases/tsq_docstrings.py new/blue-0.7.0/tests/bad_cases/tsq_docstrings.py --- old/blue-0.6.0/tests/bad_cases/tsq_docstrings.py 1970-01-01 01:00:00.000000000 +0100 +++ new/blue-0.7.0/tests/bad_cases/tsq_docstrings.py 2021-08-17 05:09:01.000000000 +0200 @@ -0,0 +1,12 @@ +'''This is a module docstring.''' +# Test triple-single-quotes docstrings. + + +class Test: + '''This is a class docstring.''' + pass + + +def test(): + '''This is a func docstring.''' + pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/tests/good_cases/decorators.py new/blue-0.7.0/tests/good_cases/decorators.py --- old/blue-0.6.0/tests/good_cases/decorators.py 1970-01-01 01:00:00.000000000 +0100 +++ new/blue-0.7.0/tests/good_cases/decorators.py 2021-08-17 05:09:01.000000000 +0200 @@ -0,0 +1,16 @@ +# Reference: https://github.com/grantjenks/blue/issues/53 + + +def get_dec_dec(): + def get_dec(): + def dec(func): + print(func) + + return dec + + return get_dec + + +@get_dec_dec()() +def foo(): + ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/tests/good_cases/demo.py new/blue-0.7.0/tests/good_cases/demo.py --- old/blue-0.6.0/tests/good_cases/demo.py 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/tests/good_cases/demo.py 2021-08-17 05:09:01.000000000 +0200 @@ -62,3 +62,11 @@ 7, 8, ] + + +def non_docstring_dq_tqs(): + x = """ +This is a multiline TQS +It's even got an embedded single quote +And it has an embedded ''' +\"""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/tests/good_cases/tdq_docstrings.py new/blue-0.7.0/tests/good_cases/tdq_docstrings.py --- old/blue-0.6.0/tests/good_cases/tdq_docstrings.py 1970-01-01 01:00:00.000000000 +0100 +++ new/blue-0.7.0/tests/good_cases/tdq_docstrings.py 2021-08-17 05:09:01.000000000 +0200 @@ -0,0 +1,32 @@ +"""This is a module docstring. + +Test triple-double-quotes docstrings. +""" + + +class Test1: + """This is a class docstring.""" + + pass + + +class Test2: + """This is a class docstring. + + And there's more. + """ + + pass + + +def test1(): + """This is a func docstring.""" + pass + + +def test2(): + """This is a func docstring. + + And there's more. + """ + pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/tests/test_blue.py new/blue-0.7.0/tests/test_blue.py --- old/blue-0.6.0/tests/test_blue.py 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/tests/test_blue.py 2021-08-17 05:09:01.000000000 +0200 @@ -1,3 +1,4 @@ +import asyncio import pathlib import subprocess @@ -22,8 +23,11 @@ test_dir = tests_dir / test_dir monkeypatch.chdir(test_dir) monkeypatch.setattr('sys.argv', ['blue', '--check', '.']) + for path in test_dir.rglob('*'): + path.touch() # Invalidate file caches in Blue. black.find_project_root.cache_clear() with pytest.raises(SystemExit) as exc_info: + asyncio.set_event_loop(asyncio.new_event_loop()) blue.main() assert exc_info.value.code == 0 @@ -36,8 +40,11 @@ test_dir = tests_dir / test_dir monkeypatch.chdir(test_dir) monkeypatch.setattr('sys.argv', ['blue', '--check', '.']) + for path in test_dir.rglob('*'): + path.touch() # Invalidate file caches in Blue. black.find_project_root.cache_clear() with pytest.raises(SystemExit) as exc_info: + asyncio.set_event_loop(asyncio.new_event_loop()) blue.main() assert exc_info.value.code == 1 @@ -56,5 +63,5 @@ assert exc_info.value.code == 0 out, err = capsys.readouterr() version = f'blue, version {blue.__version__}, based on black {black.__version__}\n' - assert out == version + assert out.endswith(version) assert err == '' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blue-0.6.0/tox.ini new/blue-0.7.0/tox.ini --- old/blue-0.6.0/tox.ini 2021-02-12 06:25:05.000000000 +0100 +++ new/blue-0.7.0/tox.ini 2021-08-17 05:09:01.000000000 +0200 @@ -11,6 +11,7 @@ [pytest] addopts= --cov blue + --cov-branch testpaths=blue docs tests [testenv:blue] @@ -38,7 +39,7 @@ commands=rstcheck --report warning README.rst [coverage:report] -fail_under=87 +fail_under=85 show_missing=true [coverage:run] @@ -56,3 +57,4 @@ E203 E303 W503 +max-line-length=88 ++++++ support-new-flake8.patch ++++++ Index: blue-0.7.0/blue/__init__.py =================================================================== --- blue-0.7.0.orig/blue/__init__.py +++ blue-0.7.0/blue/__init__.py @@ -332,7 +332,7 @@ def format_file_in_place(*args, **kws): return black_format_file_in_place(*args, **kws) -class MergedConfigParser(flake8_config.MergedConfigParser): +class MergedConfigParser(flake8_config.ConfigParser): def _parse_config(self, config_parser, parent=None): """Skip option parsing in flake8's config parsing.""" config_dict = {} @@ -382,7 +382,6 @@ def main(): ) # Change the config param callback to support setup.cfg, tox.ini, etc. config_param = black.main.params[21] - assert config_param.name == 'config' config_param.callback = read_configs # Change the version string by adding a redundant Click `version_option` # decorator on `black.main`. Fortunately the added `version_option` takes