[
  {
    "path": ".editorconfig",
    "content": "# Check http://editorconfig.org for more information\n# This is the main config file for this project:\nroot = true\n\n[*]\ncharset = utf-8\ntrim_trailing_whitespace = true\nend_of_line = lf\nindent_style = space\ninsert_final_newline = true\nindent_size = 2\n\n[*.py]\nindent_size = 4\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n- package-ecosystem: pip\n  directory: \"/\"\n  schedule:\n    interval: daily\n    time: \"02:00\"\n  open-pull-requests-limit: 10\n- package-ecosystem: github-actions\n  directory: \"/\"\n  schedule:\n    interval: daily\n    time: \"02:00\"\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: test\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']\n\n    steps:\n    - uses: actions/checkout@v4\n    - name: Set up Python ${{ matrix.python-version }}\n      uses: actions/setup-python@v5\n      with:\n        python-version: ${{ matrix.python-version }}\n\n    - name: Install poetry\n      run: |\n        curl -sSL \"https://install.python-poetry.org\" | python\n\n        # Adding `poetry` to `$PATH`:\n        echo \"$HOME/.poetry/bin\" >> $GITHUB_PATH\n\n    - name: Install dependencies\n      run: |\n        poetry config virtualenvs.in-project true\n        poetry run pip install -U pip\n        poetry install\n\n    - name: Run tests\n      run: |\n        poetry run flake8 .\n        poetry run mypy flake8_eradicate.py\n        poetry run pytest\n        poetry check\n        poetry run pip check\n\n    - name: Upload coverage to Codecov\n      if: matrix.python-version == 3.12\n      uses: codecov/codecov-action@v5\n      with:\n        file: ./coverage.xml\n"
  },
  {
    "path": ".gitignore",
    "content": "#### joe made this: http://goel.io/joe\n#### python ####\n# Byte-compiled / optimized / DLL files\n.pytest_cache\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n.hypothesis/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# pyenv\n.python-version\n\n# celery beat schedule file\ncelerybeat-schedule\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n#### macos ####\n# General\n*.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n#### windows ####\n# Windows thumbnail cache files\nThumbs.db\nehthumbs.db\nehthumbs_vista.db\n\n# Dump file\n*.stackdump\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n#### linux ####\n*~\n\n# temporary files which can be created if a process still has a handle open of a deleted file\n.fuse_hidden*\n\n# KDE directory preferences\n.directory\n\n# Linux trash folder which might appear on any partition or disk\n.Trash-*\n\n# .nfs files are created when an open file is removed but is still being accessed\n.nfs*\n#### jetbrains ####\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm\n# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839\n\n# User-specific stuff:\n.idea/\n\n## File-based project format:\n*.iws\n\n## Plugin-specific files:\n\n# IntelliJ\n/out/\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Cursive Clojure plugin\n.idea/replstate.xml\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\nfabric.properties\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Version history\n\nWe follow Semantic Versions since the `0.1.0` release.\n\n\n## 1.5.0\n\n### Features\n\n- Drops `python3.7` support, because it has almost reached its EOL\n- Adds `flake8@6` support and drops support of `flake8<5`\n\n### Misc\n\n- Updates many dependencies\n\n\n## 1.4.0\n\n### Features\n\n- Drops `python3.6` support\n- Switches from `pkg_resources` to `importlib_metadata`\n\n### Misc\n\n- Uses `poetry@1.2`\n\n\n## 1.3.0\n\n### Features\n\n- Adds `flake8@5.0` support\n\n\n## 1.2.1\n\n### Bugfixes\n\n- Adds `setuptools` in the dependencies\n\n\n## 1.2.0\n\n### Features\n\n- Adds `flake8@4.0.0` support\n- Adds `python3.10` support\n\n\n## 1.1.0\n\n### Features\n\n- Improves performance on long files #210\n\n\n## 1.0.0\n\n### Features\n\n- Adds `python3.9` support\n- Now using new `eradicate` API\n- Adds `--eradicate-whitelist` and `--eradicate-whitelist-append` options\n\n### Misc\n\n- Moves to Github Actions\n\n\n## 0.4.0\n\n### Features\n\n- Adds `python3.5` support\n\n\n## 0.3.0\n\n### Features\n\n- Adds `python3.8` support\n\n\n## 0.2.4\n\n### Bugfixes\n\n- Fixes that some lines inside the docstrings were marked as commented out code\n\n\n## 0.2.3\n\n### Bugfixes\n\n- Fixed `argparse` bug, see [#76](https://github.com/sobolevn/flake8-eradicate/issues/76)\n\n\n## 0.2.2\n\n### Bugfixes\n\n- Now `eradicate-aggressive` is parsed from config\n\n\n## 0.2.1\n\n### Features\n\n- Updates to `flake8 >= 3.7`\n- Updates `attrs < 20`\n- Fixes plugin to work with `stdin`\n\n### Misc\n\n- Changes how we use `flake8`, moves from `pytest-flake8` to native CLI\n\n\n## Version 0.2.0\n\n### Features\n\n- Adds `aggressive` configuration option\n- Upgrades `eradicate` to `1.0`\n\n\n## Version 0.1.2\n\n### Misc\n\n- Improves readme\n- Improves tests\n\n\n## Version 0.1.1\n\n### Bugfixes\n\n- Relies on `attrs` explicitly, see [#2](https://github.com/sobolevn/flake8-eradicate/issues/2)\n\n### Misc\n\n- Improves readme\n- Improves tests\n\n\n## Version 0.1.0\n\n- Initial release\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# How to contribute\n\nIf you want to start working on this project,\nyou will need to get familiar with these APIs:\n\n- [Writing a `flake8` plugin](http://flake8.pycqa.org/en/latest/plugin-development/)\n- [Using `ast` module](https://docs.python.org/3/library/ast.html)\n\nIt is also recommended to take a look at these resources:\n\n- [Missing `ast` guide](https://greentreesnakes.readthedocs.io/en/latest/)\n\n\n## Dependencies\n\nWe use [`poetry`](https://github.com/sdispater/poetry) to manage the dependencies.\n\nTo install them you would need to run two commands:\n\n```bash\npoetry install\npoetry develop\n```\n\nTo activate your `virtualenv` run `poetry shell`.\n\n\n## Tests\n\nWe use `pytest` and `flake8` for quality control.\nWe also use `wemake_python_styleguide` itself\nto develop `wemake_python_styleguide`.\n\nTo run all tests:\n\n```bash\npytest\n```\n\nThis step is mandatory during the CI.\n\n\n## Type checks\n\nWe use `mypy` to run type checks on our code.\nTo use it:\n\n```bash\nmypy flake8_eradicate.py\n```\n\nThis step is mandatory during the CI.\n\n\n## Before submitting\n\nBefore submitting your code please do the following steps:\n\n1. Run `pytest` to make sure everything was working before\n2. Add any changes you want\n3. Adds tests for the new changes\n4. Edit documentation if you have changed something significant\n5. Run `pytest` again to make sure it is still working\n6. Run `mypy` to ensure that types are correct\n\n\n## Other help\n\nYou can contribute by spreading a word about this library.\nIt would also be a huge contribution to write\na short article on how you are using this project.\nWhat are your best-practices?\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 Nikita Sobolev\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# flake8-eradicate\n\n[![wemake.services](https://img.shields.io/badge/-wemake.services-green.svg?label=%20&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC%2FxhBQAAAAFzUkdCAK7OHOkAAAAbUExURQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP%2F%2F%2F5TvxDIAAAAIdFJOUwAjRA8xXANAL%2Bv0SAAAADNJREFUGNNjYCAIOJjRBdBFWMkVQeGzcHAwksJnAPPZGOGAASzPzAEHEGVsLExQwE7YswCb7AFZSF3bbAAAAABJRU5ErkJggg%3D%3D)](https://wemake-services.github.io)\n[![Build Status](https://github.com/wemake-services/flake8-eradicate/workflows/test/badge.svg?branch=master&event=push)](https://github.com/wemake-services/flake8-eradicate/actions?query=workflow%3Atest)\n[![codecov](https://codecov.io/gh/wemake-services/flake8-eradicate/branch/master/graph/badge.svg)](https://codecov.io/gh/wemake-services/flake8-eradicate)\n[![Python Version](https://img.shields.io/pypi/pyversions/flake8-eradicate.svg)](https://pypi.org/project/flake8-eradicate/)\n[![PyPI version](https://badge.fury.io/py/flake8-eradicate.svg)](https://pypi.org/project/flake8-eradicate/)\n[![wemake-python-styleguide](https://img.shields.io/badge/style-wemake-000000.svg)](https://github.com/wemake-services/wemake-python-styleguide)\n\n`flake8` plugin to find commented out (or so called \"dead\") code.\n\nThis is quite important for the project in a long run.\nBased on [`eradicate`](https://github.com/myint/eradicate) project.\n\n\n## Installation\n\n```bash\npip install flake8-eradicate\n```\n\nIt is also a valuable part of [`wemake-python-styleguide`](https://github.com/wemake-services/wemake-python-styleguide).\n\n\n## Usage\n\nRun your `flake8` checker [as usual](http://flake8.pycqa.org/en/latest/user/invocation.html).\nCommented code should raise an error.\n\nExample:\n\n```bash\nflake8 your_module.py\n```\n\n\n## Options\n\n- `--eradicate-aggressive` to enable aggressive mode from `eradicate`, can lead to false positives\n- `--eradicate-whitelist` to overwrite the whitelist from `eradicate` (`#` separated list)\n- `--eradicate-whitelist-extend` to extend the whitelist from `eradicate` (`#` separated list)\n\n\n## Error codes\n\n| Error code |        Description       |\n|:----------:|:------------------------:|\n|    E800    | Found commented out code |\n\n\n## Output example\n\nHere's how output looks like (we are using [`wemake` formatter](https://wemake-python-styleguide.rtfd.io/en/latest/pages/usage/formatter.html)):\n\n\n\n![flake8-eradicate output](https://raw.githubusercontent.com/wemake-services/flake8-eradicate/master/eradicate.png)\n\n\n## License\n\nMIT.\n"
  },
  {
    "path": "flake8_eradicate.py",
    "content": "import tokenize\nfrom importlib import metadata as importlib_metadata\nfrom typing import (\n    Any,\n    ClassVar,\n    Dict,\n    Iterable,\n    Iterator,\n    List,\n    Optional,\n    Sequence,\n    Tuple,\n    Type,\n)\n\nfrom eradicate import Eradicator\nfrom flake8.options.manager import OptionManager\n\n#: This is a name that we use to install this library:\npkg_name = 'flake8-eradicate'\n\n#: We store the version number inside the `pyproject.toml`:\npkg_version = importlib_metadata.version(pkg_name)\n\n\nclass Checker(object):\n    \"\"\"Flake8 plugin to find commented out code.\"\"\"\n\n    name = pkg_name\n    version = pkg_version\n\n    _error_template = 'E800 Found commented out code'\n\n    options: ClassVar[Optional[Dict[str, Any]]] = None  # type: ignore\n\n    def __init__(\n        self,\n        tree,  # that's the hack we use to trigger this check\n        file_tokens: List[tokenize.TokenInfo],\n        lines: Sequence[str],\n    ) -> None:\n        \"\"\"\n        ``flake8`` plugin constructor.\n\n        Arguments:\n            file_tokens: all tokens for this file.\n            lines: all file lines.\n\n        \"\"\"\n        self._file_tokens = file_tokens\n        self._lines = lines\n        self._options = {\n            'aggressive': self.options.eradicate_aggressive,  # type: ignore\n        }\n\n        self._eradicator = Eradicator()\n\n        whitelist = self.options.eradicate_whitelist  # type: ignore\n        whitelist_ext = self.options.eradicate_whitelist_extend  # type: ignore\n\n        if whitelist_ext:\n            self._eradicator.update_whitelist(\n                whitelist_ext.split('#'),\n                extend_default=True,\n            )\n        elif whitelist:\n            self._eradicator.update_whitelist(\n                whitelist.split('#'),\n                extend_default=False,\n            )\n\n    @classmethod\n    def add_options(cls, parser: OptionManager) -> None:\n        \"\"\"\n        ``flake8`` api method to register new plugin options.\n\n        See :class:`.Configuration` docs for detailed options reference.\n\n        Arguments:\n            parser: ``flake8`` option parser instance.\n\n        \"\"\"\n        parser.add_option(\n            '--eradicate-aggressive',\n            default=False,\n            help=(\n                'Enables aggressive mode for eradicate; '\n                'this may result in false positives'\n            ),\n            action='store_true',\n            parse_from_config=True,\n        )\n        parser.add_option(\n            '--eradicate-whitelist',\n            default=False,\n            help=(\n                'String of \"#\" separated comment beginnings to whitelist '\n                'for eradicate. '\n                'Single parts are interpreted as regex. '\n                'OVERWRITING the default whitelist: {0}'\n            ).format(Eradicator.DEFAULT_WHITELIST),\n            action='store',\n            parse_from_config=True,\n        )\n        parser.add_option(\n            '--eradicate-whitelist-extend',\n            default=False,\n            help=(\n                'String of \"#\" separated comment beginnings to whitelist '\n                'for eradicate. '\n                'Single parts are interpreted as regex. '\n                'Overwrites --eradicate-whitelist. '\n                'EXTENDING the default whitelist: {0} '\n            ).format(Eradicator.DEFAULT_WHITELIST),\n            action='store',\n            parse_from_config=True,\n        )\n\n    @classmethod\n    def parse_options(cls, options) -> None:\n        \"\"\"Parses registered options for providing them to each visitor.\"\"\"\n        cls.options = options\n\n    def run(self) -> Iterator[Tuple[int, int, str, Type['Checker']]]:\n        \"\"\"Runs on each step of flake8.\"\"\"\n        for line_no in self._lines_with_commented_out_code():\n            yield line_no, 0, self._error_template, type(self)\n\n    def _lines_with_commented_out_code(self) -> Iterable[int]:\n        \"\"\"\n        Yield the physical line number that contain commented out code.\n\n        This test relies on eradicate function to remove commented out code\n        from a physical line.\n\n        Physical lines might appear like commented code although they are part\n        of a multi-line docstring (e.g. a `# noqa: DAR201` comment to suppress\n        flake8 warning about missing returns in the docstring).\n        To prevent this false-positive, the tokens of the physical line are\n        checked for a comment. The eradicate function is only invokes,\n        when the tokens indicate a comment in the physical line.\n        \"\"\"\n        comment_in_file = any(\n            token.type == tokenize.COMMENT\n            for token in self._file_tokens\n        )\n\n        if comment_in_file:\n            for line_no, line in enumerate(self._lines):\n                filtered_source = ''.join(\n                    self._eradicator.filter_commented_out_code(\n                        line,\n                        aggressive=self._options['aggressive'],\n                    ),\n                )\n                if line != filtered_source:\n                    yield line_no + 1\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[tool.poetry]\nname = \"flake8-eradicate\"\nversion = \"1.5.0\"\ndescription = \"Flake8 plugin to find commented out code\"\n\nlicense = \"MIT\"\n\nauthors = [\n  \"Nikita Sobolev <mail@sobolevn.me>\"\n]\n\nreadme = \"README.md\"\n\nrepository = \"https://github.com/wemake-services/flake8-eradicate\"\nhomepage = \"https://github.com/wemake-services/flake8-eradicate\"\n\nkeywords = [\n  \"flake8\",\n  \"plugin\",\n  \"linting\",\n  \"wemake.services\",\n  \"code quality\"\n]\n\nclassifiers = [\n  \"Development Status :: 5 - Production/Stable\",\n  \"Environment :: Console\",\n  \"Framework :: Flake8\",\n  \"Intended Audience :: Developers\",\n  \"Operating System :: OS Independent\",\n  \"Topic :: Software Development :: Libraries :: Python Modules\",\n  \"Topic :: Software Development :: Quality Assurance\",\n]\n\n[tool.poetry.urls]\n\"Funding\" = \"https://opencollective.com/wemake-python-styleguide\"\n\n[tool.poetry.dependencies]\npython = \"^3.8\"\n\nflake8 = \">5\"\neradicate = \"^2.0\"\nattrs = \"*\"\n\n[tool.poetry.group.test.dependencies]\npytest = \">=7.3,<9.0\"\npytest-cov = \">=4,<6\"\npytest-randomly = \"^3.12\"\n\nmypy = \"^1.3\"\nsafety = \">=2.3,<4.0\"\n\n[tool.poetry.plugins.\"flake8.extension\"]\nE8 = \"flake8_eradicate:Checker\"\n\n\n[build-system]\nrequires = [\"poetry-core>=1.6.0\"]\nbuild-backend = \"poetry.core.masonry.api\"\n"
  },
  {
    "path": "setup.cfg",
    "content": "# All configuration for plugins and other utils is defined here.\n# Read more about `setup.cfg`:\n# https://docs.python.org/3/distutils/configfile.html\n\n\n[flake8]\nshow-source = True\nstatistics = False\ndoctests = True\n\n# Flake plugins:\nmax-complexity = 6\nmax-line-length = 80\ninline-quotes = single\neradicate-aggressive = True\n\nexclude =\n  .git\n  __pycache__\n  .venv\n  .eggs\n  *.egg\n  tests/fixtures\n\nignore =\n  # Disable some pydocstyle checks:\n  D100 D104 D106 D401\n\n\n[tool:pytest]\n# py.test options:\nnorecursedirs = tests/fixtures *.egg .eggs dist build docs .tox .git __pycache__\n\n# You will need to measure your tests speed with `-n auto` and without it,\n# so you can see whether it gives you any performance gain, or just gives\n# you an overhead. See `docs/template/development-process.rst`.\naddopts =\n  --doctest-modules\n  --cov=flake8_eradicate\n  --cov-branch\n  --cov-report=term:skip-covered\n  --cov-report=html\n  --cov-report=xml\n  --cov-fail-under=100\n\n\n[isort]\n# isort configuration:\n# https://github.com/timothycrosley/isort/wiki/isort-Settings\nprofile = wemake\n\n\n[mypy]\n# The mypy configurations: http://bit.ly/2zEl9WI\nenable_error_code = truthy-bool, redundant-expr, unused-awaitable\n\nallow_redefinition = false\ncheck_untyped_defs = true\ndisallow_untyped_decorators = true\ndisallow_any_explicit = true\ndisallow_any_generics = true\ndisallow_untyped_calls = true\nignore_errors = false\nignore_missing_imports = true\nimplicit_reexport = false\nlocal_partial_types = true\nstrict_optional = true\nstrict_equality = true\nno_implicit_optional = true\n# We use `type: ignore` to get `importlib.metadata` version.\nwarn_unused_ignores = false\nwarn_redundant_casts = true\nwarn_unused_configs = true\nwarn_unreachable = true\nwarn_no_return = true\n"
  },
  {
    "path": "tests/conftest.py",
    "content": "import os\nimport tokenize\nfrom typing import List\n\nimport pytest\n\n\n@pytest.fixture(scope='session')\ndef absolute_path():\n    \"\"\"Fixture to create full path relative to `contest.py` inside tests.\"\"\"\n    def factory(*files):\n        dirname = os.path.dirname(__file__)\n        return os.path.join(dirname, *files)\n    return factory\n\n\n@pytest.fixture(scope='session')\ndef get_file_tokens():\n    \"\"\"Fixture to generate tokens for a given filename.\"\"\"\n    def factory(filename: str) -> List[tokenize.TokenInfo]:\n        with open(filename) as file_obj:\n            return list(tokenize.generate_tokens(file_obj.readline))\n    return factory\n\n\n@pytest.fixture(scope='session')\ndef get_file_lines():\n    \"\"\"Fixture to read file into a sequence of lines for a given filename.\"\"\"\n    def factory(filename: str) -> List[str]:\n        with open(filename) as file_obj:\n            return file_obj.readlines()\n    return factory\n"
  },
  {
    "path": "tests/fixtures/correct.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nSome docs string in a module.\n\nSome code example here:\n\n>>> x = (1 / 2) * 2\n>>> min(x, 0)\n0\n\n\"\"\"\n\nclass Some(object):\n    \"\"\"\n    Docstring inside a class.\n\n    Contains some code:\n\n        instance = Some()\n        print('Test', instance.other_property)\n\n    \"\"\"\n\n    #: Doc comment with some code: property_name = 1\n    property_name = 1\n\n    # Regular comment with some code: other_property: int = 2\n    other_property: int = 2\n\n    def some_method(self) -> None:\n        \"\"\"Comment inside a method.\"\"\"\n        print('not True and not False')\n\n        # Some logics: count(numbers) or print(False)\n        print(12 + 23 / 3)\n\n\ndef some_function():\n    \"\"\"\n    Test for noqa comments in docstrings.\n\n    This function has a multi-line doc string, but no return value is\n    stipulated, while the function defines a return. This would raise DAR201\n    flake8 violation. To suppress this raise violation the following noqa\n    comment is defined in the docstring.\n\n    # noqa: DAR201\n\n    This noqa comment should not be detected as commented out code. `eradicate`\n    itself does not raise this as a violation.\n\n    \"\"\"\n    return \"something\"\n"
  },
  {
    "path": "tests/fixtures/correct_no_comment.py",
    "content": "class Some(object):\n\n    property_name = 1\n\n    other_property: int = 2\n\n    def some_method(self) -> None:\n        print('not True and not False')\n\n        print(12 + 23 / 3)\n\n\ndef some_function():\n    return \"something\"\n"
  },
  {
    "path": "tests/fixtures/incorrect.py",
    "content": "\nclass Some(object):\n    # property_name = 1\n    # typed_property: int = 10\n    other_property = 2\n\n# fmt: on\n\n# def function_name():\n#     return None\n\n# fmt: off\n\n# class CommentedClass(object):\n#     def __init__(self, prop: int) -> None:\n#         self.property = prop\n\n#     def __str__(self) -> str:\n#         return self.__class__.__name__\n\n#    def set_prop(self, prop: int):\n#        self.prop = prop\n\n#    def get_prop(self):\n#        return self.prop\n"
  },
  {
    "path": "tests/test_comments.py",
    "content": "import subprocess\nfrom collections import namedtuple\n\nfrom flake8_eradicate import Checker\n\n\ndef test_correct_fixture(absolute_path):\n    \"\"\"End-to-End test to check that correct code works.\"\"\"\n    filename = absolute_path('fixtures', 'correct.py')\n    process = subprocess.Popen(\n        [\n            'flake8',\n            '--isolated',\n            '--show-source',\n            '--select',\n            'E8',\n            filename,\n        ],\n        stdout=subprocess.PIPE,\n        stderr=subprocess.PIPE,\n    )\n    stdout, _ = process.communicate()\n\n    assert stdout.count(b'E800') == 0\n\n\ndef test_incorrect_fixture(absolute_path):\n    \"\"\"End-to-End test to check that incorrect code raises warning.\"\"\"\n    filename = absolute_path('fixtures', 'incorrect.py')\n    process = subprocess.Popen(\n        [\n            'flake8',\n            '--isolated',\n            '--show-source',\n            '--select',\n            'E8',\n            filename,\n        ],\n        stdout=subprocess.PIPE,\n        stderr=subprocess.PIPE,\n    )\n    stdout, _ = process.communicate()\n\n    assert stdout.count(b'E800') == 7\n    assert b'# property_name = 1' in stdout\n    assert b'# typed_property: int = 10' in stdout\n\n\ndef test_incorrect_fixture_aggressive(absolute_path):\n    \"\"\"End-to-End test to check that incorrect code raises warning.\"\"\"\n    filename = absolute_path('fixtures', 'incorrect.py')\n    process = subprocess.Popen(\n        [\n            'flake8',\n            '--eradicate-aggressive',\n            '--isolated',\n            '--show-source',\n            '--select',\n            'E8',\n            filename,\n        ],\n        stdout=subprocess.PIPE,\n        stderr=subprocess.PIPE,\n    )\n    stdout, _ = process.communicate()\n    assert stdout.count(b'E800') == 13\n    assert b'# property_name = 1' in stdout\n    assert b'# typed_property: int = 10' in stdout\n    assert b'# def function_name():' in stdout\n    assert b'# class CommentedClass(object):' in stdout\n\n\ndef test_incorrect_fixture_whitelist(absolute_path):\n    \"\"\"End-to-End test to check that incorrect code raises warning.\"\"\"\n    filename = absolute_path('fixtures', 'incorrect.py')\n    process = subprocess.Popen(\n        [\n            'flake8',\n            '--eradicate-whitelist',\n            'just#overwrite',\n            '--isolated',\n            '--show-source',\n            '--select',\n            'E8',\n            filename,\n        ],\n        stdout=subprocess.PIPE,\n        stderr=subprocess.PIPE,\n    )\n    stdout, _ = process.communicate()\n\n    assert stdout.count(b'E800') == 9\n    assert b'# property_name = 1' in stdout\n    assert b'# typed_property: int = 10' in stdout\n    assert b'# fmt: on' in stdout\n    assert b'# fmt: off' in stdout\n\n\ndef test_incorrect_fixture_whitelist_extend(absolute_path):\n    \"\"\"End-to-End test to check that incorrect code raises warning.\"\"\"\n    filename = absolute_path('fixtures', 'incorrect.py')\n    process = subprocess.Popen(\n        [\n            'flake8',\n            '--eradicate-whitelist-extend',\n            'return',\n            '--isolated',\n            '--show-source',\n            '--select',\n            'E8',\n            filename,\n        ],\n        stdout=subprocess.PIPE,\n        stderr=subprocess.PIPE,\n    )\n    stdout, _ = process.communicate()\n\n    assert stdout.count(b'E800') == 4\n    assert b'# property_name = 1' in stdout\n    assert b'return' not in stdout\n    assert b'# typed_property: int = 10' in stdout\n\n\ndef test_lines_with_commented_out_code_incorrect_fixture_output(\n    absolute_path,\n    get_file_lines,\n    get_file_tokens,\n):\n    \"\"\"Verify central underlying method is returning correct output.\"\"\"\n    filename = absolute_path('fixtures', 'incorrect.py')\n\n    OptionsStub = namedtuple(\n        'Options',\n        'eradicate_aggressive eradicate_whitelist eradicate_whitelist_extend',\n    )\n    Checker.options = OptionsStub(\n        eradicate_aggressive=True,\n        eradicate_whitelist=False,\n        eradicate_whitelist_extend=False,\n    )\n\n    checker = Checker(\n        tree=None,\n        lines=get_file_lines(filename),\n        file_tokens=get_file_tokens(filename),\n    )\n    output = list(checker._lines_with_commented_out_code())\n    assert output == [3, 4, 9, 10, 14, 15, 16, 18, 19, 21, 22, 24, 25]\n\n\ndef test_lines_with_commented_out_code_file_no_comment(\n    absolute_path,\n    get_file_tokens,\n    get_file_lines,\n):\n    \"\"\"Make sure file without comment are ignored.\"\"\"\n    filename = absolute_path('fixtures', 'correct_no_comment.py')\n\n    OptionsStub = namedtuple(\n        'Options',\n        'eradicate_aggressive eradicate_whitelist eradicate_whitelist_extend',\n    )\n    Checker.options = OptionsStub(\n        eradicate_aggressive=True,\n        eradicate_whitelist=False,\n        eradicate_whitelist_extend=False,\n    )\n\n    checker = Checker(\n        tree=None,\n        lines=get_file_lines(filename),\n        file_tokens=get_file_tokens(filename),\n    )\n    output = list(checker._lines_with_commented_out_code())\n    assert output == []\n"
  },
  {
    "path": "tests/test_version.py",
    "content": "import subprocess\n\nfrom flake8_eradicate import pkg_name, pkg_version\n\n\ndef test_call_flake8_version():\n    \"\"\"Checks that module is registered and visible in the meta data.\"\"\"\n    output = subprocess.check_output(\n        ['flake8', '--version'],\n        stderr=subprocess.STDOUT,\n    )\n\n    output_text = output.decode('utf-8')\n    assert pkg_name in output_text\n    assert pkg_version in output_text\n"
  }
]