{"id":13492512,"url":"https://github.com/econchick/interrogate","last_synced_at":"2026-02-19T13:34:26.590Z","repository":{"id":37045907,"uuid":"258385030","full_name":"econchick/interrogate","owner":"econchick","description":"Explain yourself! Interrogate a codebase for docstring coverage.","archived":false,"fork":false,"pushed_at":"2026-02-02T21:07:19.000Z","size":549,"stargazers_count":657,"open_issues_count":37,"forks_count":49,"subscribers_count":5,"default_branch":"master","last_synced_at":"2026-02-03T10:54:50.521Z","etag":null,"topics":["code-quality","coverage","documentation","hacktoberfest","python"],"latest_commit_sha":null,"homepage":"https://interrogate.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/econchick.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"econchick","ko_fi":"roguelynn","custom":["https://venmo.com/Lynn-Root","https://paypal.me/roguelynn"]}},"created_at":"2020-04-24T02:33:25.000Z","updated_at":"2026-01-21T06:30:41.000Z","dependencies_parsed_at":"2025-07-07T22:44:01.663Z","dependency_job_id":"a4c1350b-e83a-460a-a6cd-08204dff75e4","html_url":"https://github.com/econchick/interrogate","commit_stats":{"total_commits":130,"total_committers":13,"mean_commits":10.0,"dds":"0.25384615384615383","last_synced_commit":"237be78f9c6135fc1a620d211cdfdc5d3885082b"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/econchick/interrogate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/econchick%2Finterrogate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/econchick%2Finterrogate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/econchick%2Finterrogate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/econchick%2Finterrogate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/econchick","download_url":"https://codeload.github.com/econchick/interrogate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/econchick%2Finterrogate/sbom","scorecard":{"id":365721,"data":{"date":"2025-08-11","repo":{"name":"github.com/econchick/interrogate","commit":"f35a9d68f609d6ceed10f4286efc8d73b79b17cb"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 1/12 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:171: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:67: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:78: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:79: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:88: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:103: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:114: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:118: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:127: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:128: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:146: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:147: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yml:60: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/pypi.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pypi.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/pypi.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/pypi.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pypi.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/pypi.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/pypi.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pypi.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/pypi.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sanity.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/sanity.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sanity.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/sanity.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sanity.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/sanity.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sanity.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/sanity.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sanity.yml:62: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/sanity.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sanity.yml:63: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/sanity.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/windows.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/windows.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/windows.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/econchick/interrogate/windows.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:28","Warn: pipCommand not pinned by hash: .github/workflows/sanity.yml:38","Warn: pipCommand not pinned by hash: .github/workflows/sanity.yml:39","Warn: pipCommand not pinned by hash: .github/workflows/sanity.yml:52","Warn: pipCommand not pinned by hash: .github/workflows/sanity.yml:68","Info:   0 out of  25 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   6 third-party GitHubAction dependencies pinned","Info:   0 out of   5 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yml:1","Info: topLevel 'contents' permission set to 'read': .github/workflows/pypi.yml:15","Warn: no topLevel permission defined: .github/workflows/sanity.yml:1","Warn: no topLevel permission defined: .github/workflows/windows.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T11:47:55.338Z","repository_id":37045907,"created_at":"2025-08-18T11:47:55.338Z","updated_at":"2025-08-18T11:47:55.338Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29614980,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T13:04:20.082Z","status":"ssl_error","status_checked_at":"2026-02-19T13:03:33.775Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-quality","coverage","documentation","hacktoberfest","python"],"created_at":"2024-07-31T19:01:06.700Z","updated_at":"2026-02-19T13:34:26.563Z","avatar_url":"https://github.com/econchick.png","language":"Python","readme":".. image:: https://interrogate.readthedocs.io/en/latest/_static/logo_pink.png\n    :alt: Pink Sloth Logo\n\n=================================\n``interrogate``: explain yourself\n=================================\n\n.. image:: https://interrogate.readthedocs.io/en/latest/_static/interrogate_badge.svg\n   :target: https://github.com/econchick/interrogate\n   :alt: Documentation Coverage\n\n.. image:: https://codecov.io/gh/econchick/interrogate/branch/master/graph/badge.svg\n   :target: https://codecov.io/gh/econchick/interrogate\n   :alt: Testing Coverage\n\n.. image:: https://readthedocs.org/projects/interrogate/badge/?version=latest\u0026style=flat\n   :target: https://interrogate.readthedocs.io/en/latest/?badge=latest\n   :alt: Documentation Status\n\n.. image:: https://github.com/econchick/interrogate/workflows/CI/badge.svg?branch=master\n   :target: https://github.com/econchick/interrogate/actions?workflow=CI\n   :alt: CI Status\n\n.. image:: https://results.pre-commit.ci/badge/github/econchick/interrogate/master.svg\n   :target: https://results.pre-commit.ci/latest/github/econchick/interrogate/master\n   :alt: pre-commit.ci status\n\n.. start-readme\n\nInterrogate a codebase for docstring coverage.\n\nWhy Do I Need This?\n===================\n\n``interrogate`` checks your code base for missing docstrings.\n\nDocumentation should be as important as code itself. And it should live *within* code. Python `standardized \u003chttps://www.python.org/dev/peps/pep-0257/\u003e`_ docstrings, allowing for developers to navigate libraries as simply as calling ``help()`` on objects, and with powerful tools like `Sphinx \u003chttps://www.sphinx-doc.org/en/master/\u003e`_, `pydoc \u003chttps://docs.python.org/3/library/pydoc.html\u003e`_, and `Docutils \u003chttps://docutils.sourceforge.io/\u003e`_ to automatically generate HTML, LaTeX, PDFs, etc.\n\n*Enter:* ``interrogate``.\n\n``interrogate`` will tell you which methods, functions, classes, and modules have docstrings, and which do not. Use ``interrogate`` to:\n\n* Get an understanding of how well your code is documented;\n* Add it to CI/CD checks to enforce documentation on newly-added code;\n* Assess a new code base for (one aspect of) code quality and maintainability.\n\nLet's get started.\n\nRequirements\n============\n\n``interrogate`` supports Python 3.8 and above.\n\n\nInstallation\n============\n\n``interrogate`` is available on `PyPI \u003chttps://pypi.org/project/interrogate/\u003e`_ and `GitHub \u003chttps://github.com/econchick/interrogate\u003e`_. The recommended installation method is `pip \u003chttps://pip.pypa.io/en/stable/\u003e`_-installing into a `virtualenv \u003chttps://hynek.me/articles/virtualenv-lives/\u003e`_:\n\n.. code-block:: console\n\n    $ pip install interrogate\n\nExtras\n------\n\n``interrogate`` provides a way to generate a `shields.io-like coverage badge \u003c#other-usage\u003e`_ as an **SVG file**.\nTo generate a **PNG file** instead, install ``interrogate`` with the extras ``[png]``:\n\n.. code-block:: console\n\n    $ pip install interrogate[png]\n\n**NOTICE:** Additional system libraries/tools may be required in order to generate a PNG file of the coverage badge:\n\n* on Windows, install Visual C++ compiler for Cairo;\n* on macOS, install ``cairo`` and ``libffi`` (with Homebrew for example - `see note below \u003c#macos-and-cairo\u003e`_);\n* on Linux, install the ``cairo``, ``python3-dev`` and ``libffi-dev`` packages (names may vary depending on distribution).\n\nRefer to the ``cairosvg`` `documentation \u003chttps://cairosvg.org/documentation/\u003e`_ for more information.\n\nMacOS and Cairo\n^^^^^^^^^^^^^^^\n\nIf you get an error when trying to generate a badge like so:\n\n.. code-block:: console\n\n    OSError: no library called \"cairo-2\" was found\n    no library called \"cairo\" was found\n    no library called \"libcairo-2\" was found\n\n\nThen first try:\n\n.. code-block:: console\n\n    export DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/lib\n\nAnd rerun the command.\n\nUsage\n=====\n\nTry it out on a Python project:\n\n.. code-block:: console\n\n    $ interrogate [PATH]\n    RESULT: PASSED (minimum: 80.0%, actual: 100.0%)\n\n\nAdd verbosity to see a summary:\n\n.. code-block:: console\n\n    $ interrogate -v [PATH]\n\n    ================== Coverage for /Users/lynn/dev/interrogate/ ====================\n    ------------------------------------ Summary ------------------------------------\n    | Name                                  |   Total |   Miss |   Cover |   Cover% |\n    |---------------------------------------|---------|--------|---------|----------|\n    | src/interrogate/__init__.py           |       1 |      0 |       1 |     100% |\n    | src/interrogate/__main__.py           |       1 |      0 |       1 |     100% |\n    | src/interrogate/badge_gen.py          |       6 |      0 |       6 |     100% |\n    | src/interrogate/cli.py                |       2 |      0 |       2 |     100% |\n    | src/interrogate/config.py             |       8 |      0 |       8 |     100% |\n    | src/interrogate/coverage.py           |      27 |      0 |      27 |     100% |\n    | src/interrogate/utils.py              |      10 |      0 |      10 |     100% |\n    | src/interrogate/visit.py              |      18 |      0 |      18 |     100% |\n    | tests/functional/__init__.py          |       1 |      0 |       1 |     100% |\n    | tests/functional/test_cli.py          |       8 |      0 |       8 |     100% |\n    | tests/functional/test_coverage.py     |      10 |      0 |      10 |     100% |\n    | tests/unit/__init__.py                |       1 |      0 |       1 |     100% |\n    | tests/unit/test_badge_gen.py          |       8 |      0 |       8 |     100% |\n    | tests/unit/test_config.py             |      10 |      0 |      10 |     100% |\n    | tests/unit/test_utils.py              |      13 |      0 |      13 |     100% |\n    |---------------------------------------|---------|--------|---------|----------|\n    | TOTAL                                 |     124 |      0 |     124 |   100.0% |\n    ---------------- RESULT: PASSED (minimum: 80.0%, actual: 100.0%) ----------------\n\n\nAdd even *more* verbosity:\n\n\n.. code-block:: console\n\n    $ interrogate -vv [PATH]\n\n    ================== Coverage for /Users/lynn/dev/interrogate/ ====================\n    ------------------------------- Detailed Coverage -------------------------------\n    | Name                                                                |  Status |\n    |---------------------------------------------------------------------|---------|\n    | src/interrogate/__init__.py (module)                                | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | src/interrogate/__main__.py (module)                                | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | src/interrogate/badge_gen.py (module)                               | COVERED |\n    |   save_badge (L42)                                                  | COVERED |\n    |   get_badge (L87)                                                   | COVERED |\n    |   should_generate_badge (L103)                                      | COVERED |\n    |   get_color (L160)                                                  | COVERED |\n    |   create (L173)                                                     | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | src/interrogate/cli.py (module)                                     | COVERED |\n    |   main (L258)                                                       | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | src/interrogate/config.py (module)                                  | COVERED |\n    |   InterrogateConfig (L19)                                           | COVERED |\n    |   find_project_root (L61)                                           | COVERED |\n    |   find_project_config (L89)                                         | COVERED |\n    |   parse_pyproject_toml (L100)                                       | COVERED |\n    |   sanitize_list_values (L116)                                       | COVERED |\n    |   parse_setup_cfg (L139)                                            | COVERED |\n    |   read_config_file (L173)                                           | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | src/interrogate/coverage.py (module)                                | COVERED |\n    |   BaseInterrogateResult (L23)                                       | COVERED |\n    |     BaseInterrogateResult.perc_covered (L37)                        | COVERED |\n    |   InterrogateFileResult (L54)                                       | COVERED |\n    |     InterrogateFileResult.combine (L67)                             | COVERED |\n    |   InterrogateResults (L81)                                          | COVERED |\n    |     InterrogateResults.combine (L93)                                | COVERED |\n    |   InterrogateCoverage (L101)                                        | COVERED |\n    |     InterrogateCoverage._add_common_exclude (L121)                  | COVERED |\n    |     InterrogateCoverage._filter_files (L128)                        | COVERED |\n    |     InterrogateCoverage.get_filenames_from_paths (L141)             | COVERED |\n    |     InterrogateCoverage._filter_nodes (L168)                        | COVERED |\n    |     InterrogateCoverage._filter_inner_nested (L194)                 | COVERED |\n    |     InterrogateCoverage._get_file_coverage (L203)                   | COVERED |\n    |     InterrogateCoverage._get_coverage (L231)                        | COVERED |\n    |     InterrogateCoverage.get_coverage (L248)                         | COVERED |\n    |     InterrogateCoverage._get_filename (L253)                        | COVERED |\n    |     InterrogateCoverage._get_detailed_row (L264)                    | COVERED |\n    |     InterrogateCoverage._create_detailed_table (L281)               | COVERED |\n    |       InterrogateCoverage._create_detailed_table._sort_nodes (L288) | COVERED |\n    |     InterrogateCoverage._print_detailed_table (L315)                | COVERED |\n    |     InterrogateCoverage._create_summary_table (L338)                | COVERED |\n    |     InterrogateCoverage._print_summary_table (L381)                 | COVERED |\n    |     InterrogateCoverage._sort_results (L399)                        | COVERED |\n    |     InterrogateCoverage._get_header_base (L429)                     | COVERED |\n    |     InterrogateCoverage._print_omitted_file_count (L438)            | COVERED |\n    |     InterrogateCoverage.print_results (L469)                        | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | src/interrogate/utils.py (module)                                   | COVERED |\n    |   parse_regex (L21)                                                 | COVERED |\n    |   smart_open (L40)                                                  | COVERED |\n    |   get_common_base (L60)                                             | COVERED |\n    |   OutputFormatter (L80)                                             | COVERED |\n    |     OutputFormatter.should_markup (L90)                             | COVERED |\n    |     OutputFormatter.set_detailed_markup (L105)                      | COVERED |\n    |     OutputFormatter.set_summary_markup (L129)                       | COVERED |\n    |     OutputFormatter._interrogate_line_formatter (L158)              | COVERED |\n    |     OutputFormatter.get_table_formatter (L226)                      | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | src/interrogate/visit.py (module)                                   | COVERED |\n    |   CovNode (L15)                                                     | COVERED |\n    |   CoverageVisitor (L44)                                             | COVERED |\n    |     CoverageVisitor._has_doc (L58)                                  | COVERED |\n    |     CoverageVisitor._visit_helper (L65)                             | COVERED |\n    |     CoverageVisitor._is_nested_func (L112)                          | COVERED |\n    |     CoverageVisitor._is_nested_cls (L121)                           | COVERED |\n    |     CoverageVisitor._is_private (L133)                              | COVERED |\n    |     CoverageVisitor._is_semiprivate (L141)                          | COVERED |\n    |     CoverageVisitor._is_ignored_common (L151)                       | COVERED |\n    |     CoverageVisitor._has_property_decorators (L168)                 | COVERED |\n    |     CoverageVisitor._has_setters (L182)                             | COVERED |\n    |     CoverageVisitor._is_func_ignored (L193)                         | COVERED |\n    |     CoverageVisitor._is_class_ignored (L217)                        | COVERED |\n    |     CoverageVisitor.visit_Module (L221)                             | COVERED |\n    |     CoverageVisitor.visit_ClassDef (L228)                           | COVERED |\n    |     CoverageVisitor.visit_FunctionDef (L237)                        | COVERED |\n    |     CoverageVisitor.visit_AsyncFunctionDef (L246)                   | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | tests/functional/__init__.py (module)                               | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | tests/functional/test_cli.py (module)                               | COVERED |\n    |   runner (L22)                                                      | COVERED |\n    |   test_run_no_paths (L30)                                           | COVERED |\n    |   test_run_shortflags (L77)                                         | COVERED |\n    |   test_run_longflags (L106)                                         | COVERED |\n    |   test_run_multiple_flags (L124)                                    | COVERED |\n    |   test_generate_badge (L135)                                        | COVERED |\n    |   test_incompatible_options (L170)                                  | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | tests/functional/test_coverage.py (module)                          | COVERED |\n    |   test_coverage_simple (L60)                                        | COVERED |\n    |   test_coverage_errors (L73)                                        | COVERED |\n    |   test_print_results (L101)                                         | COVERED |\n    |   test_print_results_omit_covered (L130)                            | COVERED |\n    |   test_print_results_omit_none (L156)                               | COVERED |\n    |   test_print_results_omit_all_summary (L174)                        | COVERED |\n    |   test_print_results_omit_all_detailed (L198)                       | COVERED |\n    |   test_print_results_ignore_module (L226)                           | COVERED |\n    |   test_print_results_single_file (L253)                             | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | tests/unit/__init__.py (module)                                     | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | tests/unit/test_badge_gen.py (module)                               | COVERED |\n    |   test_save_badge (L26)                                             | COVERED |\n    |   test_save_badge_windows (L50)                                     | COVERED |\n    |   test_save_badge_no_cairo (L62)                                    | COVERED |\n    |   test_get_badge (L73)                                              | COVERED |\n    |   test_should_generate (L96)                                        | COVERED |\n    |   test_get_color (L115)                                             | COVERED |\n    |   test_create (L136)                                                | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | tests/unit/test_config.py (module)                                  | COVERED |\n    |   test_find_project_root (L29)                                      | COVERED |\n    |   test_find_project_config (L48)                                    | COVERED |\n    |   test_parse_pyproject_toml (L57)                                   | COVERED |\n    |   test_sanitize_list_values (L93)                                   | COVERED |\n    |   test_parse_setup_cfg (L98)                                        | COVERED |\n    |   test_parse_setup_cfg_raises (L123)                                | COVERED |\n    |   test_read_config_file_none (L134)                                 | COVERED |\n    |   test_read_config_file (L193)                                      | COVERED |\n    |   test_read_config_file_raises (L207)                               | COVERED |\n    |---------------------------------------------------------------------|---------|\n    | tests/unit/test_utils.py (module)                                   | COVERED |\n    |   test_parse_regex (L32)                                            | COVERED |\n    |   test_smart_open (L39)                                             | COVERED |\n    |   test_get_common_base (L69)                                        | COVERED |\n    |   test_get_common_base_windows (L100)                               | COVERED |\n    |   test_output_formatter_should_markup (L132)                        | COVERED |\n    |   test_output_formatter_set_detailed_markup (L163)                  | COVERED |\n    |   test_output_formatter_set_summary_markup (L206)                   | COVERED |\n    |   test_output_formatter_interrogate_line_formatter (L258)           | COVERED |\n    |   test_output_formatter_interrogate_line_formatter_windows (L319)   | COVERED |\n    |   test_output_formatter_get_table_formatter (L343)                  | COVERED |\n    |   test_output_formatter_get_table_formatter_py38 (L381)             | COVERED |\n    |   test_output_formatter_get_table_formatter_raises (L395)           | COVERED |\n    |---------------------------------------------------------------------|---------|\n\n    ------------------------------------ Summary ------------------------------------\n    | Name                                  |   Total |   Miss |   Cover |   Cover% |\n    |---------------------------------------|---------|--------|---------|----------|\n    | src/interrogate/__init__.py           |       1 |      0 |       1 |     100% |\n    | src/interrogate/__main__.py           |       1 |      0 |       1 |     100% |\n    | src/interrogate/badge_gen.py          |       6 |      0 |       6 |     100% |\n    | src/interrogate/cli.py                |       2 |      0 |       2 |     100% |\n    | src/interrogate/config.py             |       8 |      0 |       8 |     100% |\n    | src/interrogate/coverage.py           |      27 |      0 |      27 |     100% |\n    | src/interrogate/utils.py              |      10 |      0 |      10 |     100% |\n    | src/interrogate/visit.py              |      18 |      0 |      18 |     100% |\n    | tests/functional/__init__.py          |       1 |      0 |       1 |     100% |\n    | tests/functional/test_cli.py          |       8 |      0 |       8 |     100% |\n    | tests/functional/test_coverage.py     |      10 |      0 |      10 |     100% |\n    | tests/unit/__init__.py                |       1 |      0 |       1 |     100% |\n    | tests/unit/test_badge_gen.py          |       8 |      0 |       8 |     100% |\n    | tests/unit/test_config.py             |      10 |      0 |      10 |     100% |\n    | tests/unit/test_utils.py              |      13 |      0 |      13 |     100% |\n    |---------------------------------------|---------|--------|---------|----------|\n    | TOTAL                                 |     124 |      0 |     124 |   100.0% |\n    ---------------- RESULT: PASSED (minimum: 80.0%, actual: 100.0%) ----------------\n\nOther Usage\n===========\n\nGenerate a `shields.io \u003chttps://shields.io/\u003e`_ badge (like this one! |interrogate-badge| ):\n\n.. code-block:: console\n\n    $ interrogate --generate-badge PATH\n    RESULT: PASSED (minimum: 80.0%, actual: 100.0%)\n    Generated badge to /Users/lynn/dev/interrogate/docs/_static/interrogate_badge.svg\n\n`See below \u003c#badge-options\u003e`_ for more badge configuration.\n\nAdd it to your ``tox.ini`` file to enforce a level of coverage:\n\n.. code-block:: ini\n\n    [testenv:doc]\n    deps = interrogate\n    skip_install = true\n    commands =\n        interrogate --quiet --fail-under 95 src tests\n\nOr use it with `pre-commit \u003chttps://pre-commit.com/\u003e`_:\n\n.. code-block:: yaml\n\n    repos:\n      - repo: https://github.com/econchick/interrogate\n        rev: 1.7.0  # or master if you're bold\n        hooks:\n          - id: interrogate\n            args: [--quiet, --fail-under=95]\n            pass_filenames: false  # needed if excluding files with pyproject.toml or setup.cfg\n\nUse it within your code directly:\n\n.. code-block:: pycon\n\n    \u003e\u003e\u003e from interrogate import coverage\n    \u003e\u003e\u003e cov = coverage.InterrogateCoverage(paths=[\"src\"])\n    \u003e\u003e\u003e results = cov.get_coverage()\n    \u003e\u003e\u003e results\n    InterrogateResults(total=68, covered=65, missing=3)\n\n\nUse ``interrogate`` with `GitHub Actions \u003chttps://github.com/features/actions\u003e`_. Check out the `action \u003chttps://github.com/marketplace/actions/python-interrogate-check\u003e`_ written \u0026 maintained by `Jack McKew \u003chttps://github.com/JackMcKew\u003e`_ (thank you, Jack!).\n\nOr use ``interrogate`` in VSCode with the `interrogate extension \u003chttps://marketplace.visualstudio.com/items?itemName=kennethlove.interrogate\u003e`_ written \u0026 maintained by `Kenneth Love \u003chttps://thekennethlove.com/\u003e`_ (thank you, Kenneth!).\n\nConfiguration\n=============\n\nConfigure within your ``pyproject.toml`` (``interrogate`` will automatically detect a ``pyproject.toml`` file and pick up default values for the command line options):\n\n.. code-block:: console\n\n    $ interrogate -c pyproject.toml [OPTIONS] [PATHS]...\n\n.. code-block:: toml\n\n    [tool.interrogate]\n    ignore-init-method = false\n    ignore-init-module = false\n    ignore-magic = false\n    ignore-semiprivate = false\n    ignore-private = false\n    ignore-property-decorators = false\n    ignore-module = false\n    ignore-nested-functions = false\n    ignore-nested-classes = false\n    ignore-setters = false\n    ignore-overloaded-functions = false\n    fail-under = 80\n    # example values\n    exclude = [\"setup.py\", \"docs\", \"build\"]\n    # example regex\n    ignore-regex = [\"^get$\", \"^mock_.*\", \".*BaseClass.*\"]\n    ext = []\n    # possible values: sphinx (default), google\n    style = \"sphinx\"\n    # possible values: 0 (minimal output), 1 (-v), 2 (-vv)\n    verbose = 0\n    quiet = false\n    whitelist-regex = []\n    color = true\n    omit-covered-files = false\n    # output file logation\n    generate-badge = \".\"\n    badge-format = \"svg\"\n\n\nOr configure within your ``setup.cfg`` (``interrogate`` will automatically detect a ``setup.cfg`` file and pick up default values for the command line options):\n\n.. code-block:: console\n\n    $ interrogate -c setup.cfg [OPTIONS] [PATHS]...\n\n.. code-block:: ini\n\n    [tool:interrogate]\n    ignore-init-method = false\n    ignore-init-module = false\n    ignore-magic = false\n    ignore-semiprivate = false\n    ignore-private = false\n    ignore-property-decorators = false\n    ignore-module = false\n    ignore-nested-functions = false\n    ignore-nested-classes = false\n    ignore-setters = false\n    ignore-overloaded-functions = false\n    fail-under = 80\n    ; example values\n    exclude = setup.py,docs,build\n    ; example regex\n    ignore-regex = ^get$,^mock_.*,.*BaseClass.*\n    ext = []\n    ; possible values: sphinx (default), google\n    style = sphinx\n    ; possible values: 0 (minimal output), 1 (-v), 2 (-vv)\n    verbose = 0\n    quiet = false\n    whitelist-regex =\n    color = true\n    omit-covered-files = false\n    ; output file logation\n    generate-badge = .\n    badge-format = svg\n\n\n.. warning::\n\n    The use of ``setup.cfg`` is not recommended unless for very simple use cases. ``.cfg`` files use a different parser than ``pyproject.toml`` which might cause hard to track down problems. When possible, it is recommended to use ``pyproject.toml`` to define your interrogate configuration.\n\n.. _badge-opts:\n\nBadge Options\n=============\n\nBadge Format\n------------\n\nThe default file format is ``svg``. Use the ``--badge-format`` flag to create a ``png`` file instead.\n**Note**: ``interrogate`` must be installed with ``interrogate[png]`` in order to generate ``png`` files (see `above \u003c#extras\u003e`_).\n\n.. code-block:: console\n\n    $ interrogate --generate-badge PATH --badge-format png\n    RESULT: PASSED (minimum: 80.0%, actual: 100.0%)\n    Generated badge to /Users/lynn/dev/interrogate/docs/_static/interrogate_badge.png\n\nBadge Style\n-----------\n\nThe following badge styles are available via the ``--badge-style`` flag:\n\n+------------------------------------+--------------------------------+\n| option                             | example                        |\n+====================================+================================+\n| ``flat``                           | |flat-example|                 |\n+------------------------------------+--------------------------------+\n| ``flat-square``                    | |flat-square-example|          |\n+------------------------------------+--------------------------------+\n| ``flat-square-modified`` (default) | |interrogate-badge|            |\n+------------------------------------+--------------------------------+\n| ``for-the-badge``                  | |for-the-badge-example|        |\n+------------------------------------+--------------------------------+\n| ``plastic``                        | |plastic-example|              |\n+------------------------------------+--------------------------------+\n| ``social``                         | |social-example|               |\n+------------------------------------+--------------------------------+\n\n.. end-readme\n\nCommand Line Options\n====================\n\nTo view all options available, run ``interrogate --help``:\n\n.. code-block:: console\n\n    interrogate -h\n    Usage: interrogate [OPTIONS] [PATHS]...\n\n      Measure and report on documentation coverage in Python modules.\n\n    Options:\n      --version                       Show the version and exit.\n      -v, --verbose                   Level of verbosity.\n\n                                      NOTE: When configuring verbosity in\n                                      pyproject.toml or setup.cfg, `verbose=1`\n                                      maps to `-v`, and `verbose=2` maps to `-vv`.\n                                      `verbose=0` is the equivalent of no verbose\n                                      flags used, producing minimal output.\n      -q, --quiet                     Do not print output  [default: False]\n      -f, --fail-under INT | FLOAT    Fail when coverage % is less than a given\n                                      amount.  [default: 80.0]\n\n      -e, --exclude PATH              Exclude PATHs of files and/or directories.\n                                      Multiple `-e/--exclude` invocations\n                                      supported.\n\n      -i, --ignore-init-method        Ignore `__init__` method of classes.\n                                      [default: False]\n\n      -I, --ignore-init-module        Ignore `__init__.py` modules.  [default:\n                                      False]\n\n      -m, --ignore-magic              Ignore all magic methods of classes.\n                                      [default: False]\n\n                                      NOTE: This does not include the `__init__`\n                                      method. To ignore `__init__` methods, use\n                                      `--ignore-init-method`.\n\n      -M, --ignore-module             Ignore module-level docstrings.  [default:\n                                      False]\n\n      -n, --ignore-nested-functions   Ignore nested functions and methods.\n                                      [default: False]\n\n      -C, --ignore-nested-classes     Ignore nested classes.  [default: False]\n\n      -O, --ignore-overloaded-functions\n                                      Ignore `@typing.overload`-decorated functions.\n                                      [default: False]\n\n      -p, --ignore-private            Ignore private classes, methods, and\n                                      functions starting with two underscores.\n                                      [default: False]\n\n                                      NOTE: This does not include magic methods;\n                                      use `--ignore-magic` and/or `--ignore-init-\n                                      method` instead.\n\n      -P, --ignore-property-decorators\n                                      Ignore methods with property setter/getter/deleter\n                                      decorators.  [default: False]\n\n      -S, --ignore-setters            Ignore methods with property setter\n                                      decorators.  [default: False]\n\n      -s, --ignore-semiprivate        Ignore semiprivate classes, methods, and\n                                      functions starting with a single underscore.\n                                      [default: False]\n\n      -r, --ignore-regex STR          Regex identifying class, method, and\n                                      function names to ignore. Multiple\n                                      `-r/--ignore-regex` invocations supported.\n\n      --ext                           Include Python-like files with the given\n                                      extension (supported: ``pyi``). Multiple\n                                      `--ext` invocations supported.\n\n      -w, --whitelist-regex STR       Regex identifying class, method, and\n                                      function names to include. Multiple\n                                      `-w/--whitelist-regex` invocations\n                                      supported.\n\n      --style [sphinx|google]         Style of docstrings to honor. Using `google`\n                                      will consider a class and its `__init__`\n                                      method both covered if there is either a\n                                      class-level docstring, or an `__init__`\n                                      method docstring, instead of enforcing both.\n                                      Mutually exclusive with `-i`/`--ignore-init`\n                                      flag.  [default: sphinx]\n\n      -o, --output FILE               Write output to a given FILE.  [default:\n                                      stdout]\n\n      --color / --no-color            Toggle color output on/off when printing to\n                                      stdout.  [default: True]\n\n      --omit-covered-files            Omit reporting files that have 100%\n                                      documentation coverage. This option is\n                                      ignored if verbosity is not set.  [default:\n                                      False]\n\n      -g, --generate-badge PATH       Generate a 'shields.io' status badge (an SVG\n                                      image) in at a given file or directory. Will\n                                      not generate a badge if results did not\n                                      change from an existing badge of the same\n                                      path.\n\n      --badge-format [svg|png]        File format for the generated badge. Used\n                                      with the `-g/--generate-badge` flag.\n                                      [default: svg]\n\n                                      NOTE: To generate a PNG file, interrogate\n                                      must be installed with `interrogate[png]`,\n                                      i.e. `pip install interrogate[png]`.\n\n      --badge-style [flat|flat-square|flat-square-modified|for-the-badge|plastic|social]\n                                      Desired style of shields.io badge. Used with\n                                      the `-g/--generate-badge` flag. [default:\n                                      flat-square-modified]\n\n      -h, --help                      Show this message and exit.\n      -c, --config FILE               Read configuration from `pyproject.toml` or\n                                      `setup.cfg`.\n\n\n.. start-uses-this\n\nUsers of Interrogate\n====================\n\n* `attrs \u003chttps://github.com/python-attrs/attrs\u003e`_\n* `OpenMMLab \u003chttps://github.com/open-mmlab\u003e`_'s ecosystem\n* `pyjanitor \u003chttps://github.com/ericmjl/pyjanitor\u003e`_\n* `klio \u003chttps://github.com/spotify/klio\u003e`_\n\nInterrogate in the Wild\n-----------------------\n\n* `Why You Should Document Your Tests \u003chttps://hynek.me/articles/document-your-tests/\u003e`_ by `Hynek Schlawack \u003chttps://twitter.com/hynek\u003e`_\n* `Episode #181: It's time to interrogate your Python code \u003chttps://pythonbytes.fm/episodes/show/181/it-s-time-to-interrogate-your-python-code\u003e`_ - `PythonBytes podcast \u003chttps://pythonbytes.fm/\u003e`_\n\n.. end-uses-this\n\n.. start-credits\n\nCredits\n=======\n\n.. role:: smol\n\n``interrogate`` was inspired by |docstr-coverage|_, which was forked from Alexey \"DataGreed\" Strelkov's |docstring-coverage|_, which was inspired by a 2004 `recipe from James Harlow \u003chttp://code.activestate.com/recipes/355731/\u003e`_ :smol:`(turtles...)`.\n\nThe cute |sloth| logo is by `JustineW \u003chttps://thenounproject.com/wojcik.justine/\u003e`_ purchased via `the Noun Project \u003chttps://thenounproject.com/\u003e`_ (but also available under the `Creative Commons License \u003chttps://creativecommons.org/licenses/by/3.0/us/legalcode\u003e`_ with attribution).\n\n\n.. |interrogate-badge|  image:: https://interrogate.readthedocs.io/en/latest/_static/interrogate_badge.svg\n.. |flat-example| image:: https://interrogate.readthedocs.io/en/latest/_static/badge_examples/interrogate_badge_f.svg\n.. |flat-square-example| image:: https://interrogate.readthedocs.io/en/latest/_static/badge_examples/interrogate_badge_fs.svg\n.. |for-the-badge-example| image:: https://interrogate.readthedocs.io/en/latest/_static/badge_examples/interrogate_badge_ftb.svg\n.. |plastic-example| image:: https://interrogate.readthedocs.io/en/latest/_static/badge_examples/interrogate_badge_p.svg\n.. |social-example| image:: https://interrogate.readthedocs.io/en/latest/_static/badge_examples/interrogate_badge_s.svg\n.. |sloth| image:: https://interrogate.readthedocs.io/en/latest/_static/logo_smol.png\n\n.. |docstr-coverage| replace:: ``docstr-coverage``\n.. _docstr-coverage: https://pypi.org/project/docstr-coverage\n.. |docstring-coverage| replace:: ``docstring-coverage``\n.. _docstring-coverage: https://bitbucket.org/DataGreed/docstring-coverage\n\n.. end-credits\n","funding_links":["https://github.com/sponsors/econchick","https://ko-fi.com/roguelynn","https://venmo.com/Lynn-Root","https://paypal.me/roguelynn"],"categories":["Python","Documentation"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feconchick%2Finterrogate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feconchick%2Finterrogate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feconchick%2Finterrogate/lists"}