Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-eradicate for openSUSE:Factory checked in at 2023-09-20 13:28:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-eradicate (Old) and /work/SRC/openSUSE:Factory/.python-eradicate.new.16627 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-eradicate" Wed Sep 20 13:28:49 2023 rev:5 rq:1112072 version:2.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-eradicate/python-eradicate.changes 2023-06-14 16:31:59.211444615 +0200 +++ /work/SRC/openSUSE:Factory/.python-eradicate.new.16627/python-eradicate.changes 2023-09-20 13:31:20.767280917 +0200 @@ -1,0 +2,8 @@ +Mon Sep 18 19:58:36 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 2.3.0: + * This is the last release with Python2 support: + * True Windows support + * New console script + +------------------------------------------------------------------- Old: ---- eradicate-2.1.0.tar.gz test_eradicate.py New: ---- eradicate-2.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-eradicate.spec ++++++ --- /var/tmp/diff_new_pack.YKHZH3/_old 2023-09-20 13:31:21.943323050 +0200 +++ /var/tmp/diff_new_pack.YKHZH3/_new 2023-09-20 13:31:21.943323050 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-eradicate # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,14 +18,13 @@ %{?sle15_python_module_pythons} Name: python-eradicate -Version: 2.1.0 +Version: 2.3.0 Release: 0 Summary: Python utility for removing commented-out code License: MIT Group: Development/Languages/Python URL: https://github.com/myint/eradicate Source: https://files.pythonhosted.org/packages/source/e/eradicate/eradicate-%{version}.tar.gz -Source1: https://raw.githubusercontent.com/myint/eradicate/v%{version}/test_eradicate.py BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros @@ -44,7 +43,6 @@ %prep %setup -q -n eradicate-%{version} -cp %{SOURCE1} . %build %python_build ++++++ eradicate-2.1.0.tar.gz -> eradicate-2.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eradicate-2.1.0/MANIFEST.in new/eradicate-2.3.0/MANIFEST.in --- old/eradicate-2.1.0/MANIFEST.in 2022-04-06 11:43:12.000000000 +0200 +++ new/eradicate-2.3.0/MANIFEST.in 2023-06-08 18:50:05.000000000 +0200 @@ -1,3 +1,4 @@ include MANIFEST.in include README.rst exclude Makefile +include test_eradicate.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eradicate-2.1.0/PKG-INFO new/eradicate-2.3.0/PKG-INFO --- old/eradicate-2.1.0/PKG-INFO 2022-04-06 11:46:41.558620200 +0200 +++ new/eradicate-2.3.0/PKG-INFO 2023-06-09 08:30:42.625560000 +0200 @@ -1,12 +1,12 @@ Metadata-Version: 2.1 Name: eradicate -Version: 2.1.0 +Version: 2.3.0 Summary: Removes commented-out code. Home-page: https://github.com/myint/eradicate Author: Steven Myint +Maintainer: Nikita Sobolev <m...@sobolevn.me> License: Expat License Keywords: clean,format,commented-out code -Platform: UNKNOWN Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License @@ -93,5 +93,3 @@ There are different tools, plugins, and integrations for ``eradicate`` users: - `flake8-eradicate <https://github.com/sobolevn/flake8-eradicate>`_ - Flake8 plugin to find commented out or dead code. - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eradicate-2.1.0/eradicate new/eradicate-2.3.0/eradicate --- old/eradicate-2.1.0/eradicate 2022-04-06 11:43:12.000000000 +0200 +++ new/eradicate-2.3.0/eradicate 1970-01-01 01:00:00.000000000 +0100 @@ -1,47 +0,0 @@ -#!/usr/bin/env python - -# Copyright (C) 2012-2018 Steven Myint -# -# 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. - -"""eradicate utility.""" - -from __future__ import print_function - -import signal -import sys - -import eradicate - - -if __name__ == '__main__': - try: - # Exit on broken pipe. - signal.signal(signal.SIGPIPE, signal.SIG_DFL) - except AttributeError: - # SIGPIPE is not available on Windows. - pass - - try: - sys.exit(eradicate.main(sys.argv, - standard_out=sys.stdout, - standard_error=sys.stderr)) - except KeyboardInterrupt: - sys.exit(2) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eradicate-2.1.0/eradicate.egg-info/PKG-INFO new/eradicate-2.3.0/eradicate.egg-info/PKG-INFO --- old/eradicate-2.1.0/eradicate.egg-info/PKG-INFO 2022-04-06 11:46:41.000000000 +0200 +++ new/eradicate-2.3.0/eradicate.egg-info/PKG-INFO 2023-06-09 08:30:42.000000000 +0200 @@ -1,12 +1,12 @@ Metadata-Version: 2.1 Name: eradicate -Version: 2.1.0 +Version: 2.3.0 Summary: Removes commented-out code. Home-page: https://github.com/myint/eradicate Author: Steven Myint +Maintainer: Nikita Sobolev <m...@sobolevn.me> License: Expat License Keywords: clean,format,commented-out code -Platform: UNKNOWN Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License @@ -93,5 +93,3 @@ There are different tools, plugins, and integrations for ``eradicate`` users: - `flake8-eradicate <https://github.com/sobolevn/flake8-eradicate>`_ - Flake8 plugin to find commented out or dead code. - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eradicate-2.1.0/eradicate.egg-info/SOURCES.txt new/eradicate-2.3.0/eradicate.egg-info/SOURCES.txt --- old/eradicate-2.1.0/eradicate.egg-info/SOURCES.txt 2022-04-06 11:46:41.000000000 +0200 +++ new/eradicate-2.3.0/eradicate.egg-info/SOURCES.txt 2023-06-09 08:30:42.000000000 +0200 @@ -1,9 +1,10 @@ MANIFEST.in README.rst -eradicate eradicate.py setup.py +test_eradicate.py eradicate.egg-info/PKG-INFO eradicate.egg-info/SOURCES.txt eradicate.egg-info/dependency_links.txt +eradicate.egg-info/entry_points.txt eradicate.egg-info/top_level.txt \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eradicate-2.1.0/eradicate.egg-info/entry_points.txt new/eradicate-2.3.0/eradicate.egg-info/entry_points.txt --- old/eradicate-2.1.0/eradicate.egg-info/entry_points.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/eradicate-2.3.0/eradicate.egg-info/entry_points.txt 2023-06-09 08:30:42.000000000 +0200 @@ -0,0 +1,2 @@ +[console_scripts] +eradicate = eradicate:main diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eradicate-2.1.0/eradicate.py new/eradicate-2.3.0/eradicate.py --- old/eradicate-2.1.0/eradicate.py 2022-04-06 11:44:17.000000000 +0200 +++ new/eradicate-2.3.0/eradicate.py 2023-06-09 08:24:48.000000000 +0200 @@ -27,10 +27,17 @@ import difflib import io import os +import sys import re import tokenize -__version__ = '2.1.0' +try: + detect_encoding = tokenize.detect_encoding +except AttributeError: + from lib2to3.pgen2 import tokenize as lib2to3_tokenize + detect_encoding = lib2to3_tokenize.detect_encoding + +__version__ = '2.3.0' class Eradicator(object): @@ -57,7 +64,9 @@ r'noqa', r'nosec', r'type:\s*ignore', + r'mypy:', r'fmt:\s*(on|off)', + r'yapf:\s*(enable|disable)', r'isort:\s*(on|off|skip|skip_file|split|dont-add-imports(:\s*\[.*?\])?)', r'TODO', r'FIXME', @@ -211,8 +220,7 @@ """Return file encoding.""" try: with open(filename, 'rb') as input_file: - from lib2to3.pgen2 import tokenize as lib2to3_tokenize - encoding = lib2to3_tokenize.detect_encoding(input_file.readline)[0] + encoding = detect_encoding(input_file.readline)[0] # Check for correctness of encoding. with self.open_with_encoding(filename, encoding) as input_file: @@ -234,7 +242,7 @@ flags=re.IGNORECASE) -def main(argv, standard_out, standard_error): +def main(argv=sys.argv, standard_out=sys.stdout, standard_error=sys.stderr): """Main entry point.""" import argparse parser = argparse.ArgumentParser(description=__doc__, prog='eradicate') @@ -290,5 +298,10 @@ except IOError as exception: print('{}'.format(exception), file=standard_error) change_or_error = True + if change_or_error and args.error: return 1 + + +if __name__ == '__main__': + main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eradicate-2.1.0/setup.py new/eradicate-2.3.0/setup.py --- old/eradicate-2.1.0/setup.py 2022-04-06 11:43:12.000000000 +0200 +++ new/eradicate-2.3.0/setup.py 2023-06-08 18:50:05.000000000 +0200 @@ -24,6 +24,7 @@ long_description=readme.read(), license='Expat License', author='Steven Myint', + maintainer='Nikita Sobolev <m...@sobolevn.me>', url='https://github.com/myint/eradicate', classifiers=['Environment :: Console', 'Intended Audience :: Developers', @@ -33,4 +34,9 @@ 'Topic :: Software Development :: Quality Assurance'], keywords='clean, format, commented-out code', py_modules=['eradicate'], - scripts=['eradicate']) + entry_points={ + 'console_scripts': [ + 'eradicate = eradicate:main', + ], + }, + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/eradicate-2.1.0/test_eradicate.py new/eradicate-2.3.0/test_eradicate.py --- old/eradicate-2.1.0/test_eradicate.py 1970-01-01 01:00:00.000000000 +0100 +++ new/eradicate-2.3.0/test_eradicate.py 2023-06-09 08:24:34.000000000 +0200 @@ -0,0 +1,623 @@ +#!/usr/bin/env python + +"""Test suite for eradicate.""" + +from __future__ import unicode_literals + +import contextlib +import io +import subprocess +import sys +import tempfile +import unittest +try: # pragma: no cover + import mock +except ModuleNotFoundError: # pragma: no cover + import unittest.mock as mock +import re + +import eradicate + + +class UnitTests(unittest.TestCase): + + def test_comment_contains_code(self): + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '#')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# This is a (real) comment.')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# 123')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# 123.1')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# 1, 2, 3')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + 'x = 1 # x = 1')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# pylint: disable=redefined-outer-name')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# Issue #999: This is not code')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '# x = 1')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#from foo import eradicate')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#import eradicate')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#"key": value,')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#"key": "value",')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#"key": 1 + 1,')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + "#'key': 1 + 1,")) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#"key": {')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#}')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#} )]')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#},')) + + def test_comment_contains_code_with_print(self): + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#print')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#print(1)')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#print 1')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '#to print')) + + def test_comment_contains_code_with_return(self): + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#return x')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '#to return')) + + def test_comment_contains_code_with_multi_line(self): + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#def foo():')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#else:')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '# else : ')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '# "foo %d" % \\')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#elif True:')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#x = foo(')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '#except Exception:')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# this is = to that :(')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '#else')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '#or else:')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '#else True:')) + + def test_comment_contains_code_with_sentences(self): + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '#code is good')) + + def test_comment_contains_code_with_encoding(self): + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# coding=utf-8')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '#coding= utf-8')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# coding: utf-8')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# encoding: utf8')) + + self.assertTrue(eradicate.Eradicator().comment_contains_code( + '# codings=utf-8')) + + def test_comment_contains_code_with_default_whitelist(self): + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# pylint: disable=A0123')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# pylint:disable=A0123')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# pylint: disable = A0123')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# pylint:disable = A0123')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# pyright: reportErrorName=true')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# noqa')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# NOQA')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# noqa: A123')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# noqa:A123')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# nosec')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# fmt: on')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# fmt: off')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# fmt:on')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# fmt:off')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# yapf: enable')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# yapf: disable')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# yapf:enable')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# yapf:disable')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort: on')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort:on')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort: off')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort:off')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort: skip')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort:skip')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort: skip_file')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort:skip_file')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort: split')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort:split')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort: dont-add-imports')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort:dont-add-imports')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort: dont-add-imports: ["import os"]')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort:dont-add-imports: ["import os"]')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort: dont-add-imports:["import os"]')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# isort:dont-add-imports:["import os"]')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# type: ignore')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# type:ignore')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# type: ignore[import]')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# type:ignore[import]')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# mypy: ignore-errors')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# mypy: disable-error-code=[')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# mypy: warn-unreachable, strict-optional')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# TODO: Do that')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# FIXME: Fix that')) + + self.assertFalse(eradicate.Eradicator().comment_contains_code( + '# XXX: What ever')) + + + def test_commented_out_code_line_numbers(self): + self.assertEqual( + [1, 3], + list(eradicate.Eradicator().commented_out_code_line_numbers( + """\ +# print(5) +# This is a comment. +# x = 1 + +y = 1 # x = 3 + +# The below is another comment. +# 3 / 2 + 21 +"""))) + + def test_commented_out_code_line_numbers_with_errors(self): + self.assertEqual( + [1, 3], + list(eradicate.Eradicator().commented_out_code_line_numbers( + """\ +# print(5) +# This is a comment. +# x = 1 + +y = 1 # x = 3 + +# The below is another comment. +# 3 / 2 + 21 +def foo(): + 1 + 2 +"""))) + + def test_commented_out_code_line_numbers_with_with_statement(self): + self.assertEqual( + [1, 2], + list(eradicate.Eradicator().commented_out_code_line_numbers("""\ +# with open('filename', 'w') as out_file: +# json.dump(objects, out_file) +# +"""))) + + def test_commented_out_code_line_numbers_with_for_statement(self): + self.assertEqual( + [1, 2], + list(eradicate.Eradicator().commented_out_code_line_numbers("""\ +# for x in y: +# oops = x.ham +"""))) + + def test_filter_commented_out_code(self): + self.assertEqual( + """\ +# This is a comment. + +y = 1 # x = 3 + +# The below is another comment. +# 3 / 2 + 21 +""", + ''.join(eradicate.Eradicator().filter_commented_out_code( + """\ +# print(5) +# This is a comment. +# x = 1 + +y = 1 # x = 3 + +# The below is another comment. +# 3 / 2 + 21 +# try: +# x = 1 +# finally: +# x = 0 +"""))) + + def test_filter_commented_out_code_should_avoid_escaped_newlines(self): + line = """\ +if False: \\ +# print(3) + print(2) + print(3) +""" + self.assertEqual( + line, + ''.join(eradicate.Eradicator().filter_commented_out_code(line))) + + def test_filter_commented_out_code_with_larger_example(self): + self.assertEqual( + """\ +# This is a comment. + +y = 1 # x = 3 + +# The below is another comment. +# 3 / 2 + 21 +""", + ''.join(eradicate.Eradicator().filter_commented_out_code( + """\ +# print(5) +# This is a comment. +# x = 1 + +y = 1 # x = 3 + +# The below is another comment. +# 3 / 2 + 21 +"""))) + + def test_filter_commented_out_code_without_aggressive(self): + code = """\ +# iterate through choices inside of parenthesis (separated by '|'): + +# if the Optional takes a value, format is: +# -s ARGS, --long ARGS +""" + self.assertEqual( + code, + ''.join(eradicate.Eradicator().filter_commented_out_code(code, + aggressive=False))) + + def test_filter_commented_out_code_with_annotation(self): + self.assertEqual( + '\n\n\n', + ''.join(eradicate.Eradicator().filter_commented_out_code("""\ +# class CommentedClass(object): +# def __init__(self, prop: int) -> None: +# self.property = prop + +# def __str__(self) -> str: +# return self.__class__.__name__ + +# def set_prop(self, prop: int): +# self.prop = prop + +# def get_prop(self): +# return self.prop +"""))) + + def test_detect_encoding_with_bad_encoding(self): + with temporary_file('# -*- coding: blah -*-\n') as filename: + self.assertEqual('latin-1', + eradicate.Eradicator().detect_encoding(filename)) + + def test_extend_whitelist(self): + eradicator = eradicate.Eradicator() + eradicator.update_whitelist(["foo"], True) + self.assertTrue( + eradicator.WHITELIST_REGEX == re.compile( + r'|'.join(list(eradicator.DEFAULT_WHITELIST) + ["foo"]), flags=re.IGNORECASE + ) + ) + + def test_update_whitelist(self): + eradicator = eradicate.Eradicator() + eradicator.update_whitelist(["foo"], False) + self.assertTrue(eradicator.WHITELIST_REGEX == re.compile("foo", flags=re.IGNORECASE)) + + +class SystemTests(unittest.TestCase): + + def test_diff(self): + with temporary_file("""\ +# x * 3 == False +# x is a variable +""") as filename: + output_file = io.StringIO() + eradicate.main(argv=['my_fake_program', filename], + standard_out=output_file, + standard_error=None) + self.assertEqual("""\ +@@ -1,2 +1 @@ +-# x * 3 == False + # x is a variable +""", '\n'.join(output_file.getvalue().split('\n')[2:])) + + def test_recursive(self): + with temporary_directory() as directory: + + with temporary_file("""\ +# x * 3 == False +# x is a variable +""", directory=directory): + + output_file = io.StringIO() + eradicate.main(argv=['my_fake_program', + '--recursive', + directory], + standard_out=output_file, + standard_error=None) + self.assertEqual("""\ +@@ -1,2 +1 @@ +-# x * 3 == False + # x is a variable +""", '\n'.join(output_file.getvalue().split('\n')[2:])) + + def test_ignore_hidden_directories(self): + with temporary_directory() as directory: + with temporary_directory(prefix='.', + directory=directory) as inner_directory: + + with temporary_file("""\ +# x * 3 == False +# x is a variable +""", directory=inner_directory): + + output_file = io.StringIO() + eradicate.main(argv=['my_fake_program', + '--recursive', + directory], + standard_out=output_file, + standard_error=None) + self.assertEqual( + '', + output_file.getvalue().strip()) + + def test_in_place(self): + with temporary_file("""\ +# x * 3 == False +# x is a variable +""") as filename: + output_file = io.StringIO() + eradicate.main(argv=['my_fake_program', '--in-place', filename], + standard_out=output_file, + standard_error=None) + with open(filename) as f: + self.assertEqual("""\ +# x is a variable +""", f.read()) + + def test_with_missing_file(self): + output_file = io.StringIO() + ignore = StubFile() + eradicate.main(argv=['my_fake_program', '--in-place', '.fake'], + standard_out=output_file, + standard_error=ignore) + self.assertFalse(output_file.getvalue()) + + def test_returns_error_code_if_requested(self): + with temporary_file("""\ + # x * 3 == False + # x is a variable + """) as filename: + output_file = io.StringIO() + result = eradicate.main(argv=['my_fake_program', filename, "-e"], + standard_out=output_file, + standard_error=None) + self.assertTrue(result) + + def test_returns_None_if_no_error_request(self): + with temporary_file("""\ + # x * 3 == False + # x is a variable + """) as filename: + output_file = io.StringIO() + result = eradicate.main(argv=['my_fake_program', filename], + standard_out=output_file, + standard_error=None) + self.assertTrue(result is None) + + def test_end_to_end(self): + with temporary_file("""\ +# x * 3 == False +# x is a variable +""") as filename: + process = subprocess.Popen([sys.executable, '-m' + 'eradicate', filename], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + out, err = process.communicate() + self.assertEqual("""\ +@@ -1,2 +1 @@ +-# x * 3 == False + # x is a variable""", + '\n'.join(out.splitlines()[2:])) + self.assertEqual(err, '') + + def test_whitelist(self): + mock_update = mock.Mock() + with mock.patch.object(eradicate.Eradicator, 'update_whitelist', mock_update): + with temporary_file("# empty") as filename: + result = eradicate.main(argv=['my_fake_program', '--whitelist', 'foo# bar', filename], + standard_out=None, + standard_error=None) + self.assertTrue(result is None) + mock_update.assert_called_once_with(["foo", " bar"], False) + + def test_whitelist_extend(self): + mock_update = mock.Mock() + with mock.patch.object(eradicate.Eradicator, 'update_whitelist', mock_update): + with temporary_file("# empty") as filename: + result = eradicate.main(argv=['my_fake_program', '--whitelist-extend', 'foo #bar', filename], + standard_out=None, + standard_error=None) + self.assertTrue(result is None) + mock_update.assert_called_once_with(["foo ", "bar"], True) + + +@contextlib.contextmanager +def temporary_file(contents, directory='.', prefix=''): + """Write contents to temporary file and yield it.""" + f = tempfile.NamedTemporaryFile(suffix='.py', prefix=prefix, + delete=False, dir=directory) + try: + f.write(contents.encode()) + f.close() + yield f.name + finally: + import os + os.remove(f.name) + + +@contextlib.contextmanager +def temporary_directory(directory='.', prefix=''): + """Create temporary directory and yield its path.""" + temp_directory = tempfile.mkdtemp(prefix=prefix, dir=directory) + try: + yield temp_directory + finally: + import shutil + shutil.rmtree(temp_directory) + + +class StubFile(object): + + """Fake file that ignores everything.""" + + def write(*_): + """Ignore.""" + + +if __name__ == '__main__': + unittest.main()