Explain yourself! Interrogate a codebase for docstring coverage.

Overview

Pink Sloth Logo

interrogate: explain yourself

Documentation Coverage Testing Coverage Documentation Status CI Status

Interrogate a codebase for docstring coverage.

Why Do I Need This?

interrogate checks your code base for missing docstrings.

Documentation should be as important as code itself. And it should live within code. Python standardized docstrings, allowing for developers to navigate libraries as simply as calling help() on objects, and with powerful tools like Sphinx, pydoc, and Docutils to automatically generate HTML, LaTeX, PDFs, etc.

Enter: interrogate.

interrogate will tell you which methods, functions, classes, and modules have docstrings, and which do not. Use interrogate to:

  • Get an understanding of how well your code is documented;
  • Add it to CI/CD checks to enforce documentation on newly-added code;
  • Assess a new code base for (one aspect of) code quality and maintainability.

Let's get started.

Requirements

interrogate supports Python 3.6 and above.

Installation

interrogate is available on PyPI and GitHub. The recommended installation method is pip-installing into a virtualenv:

$ pip install interrogate

Usage

Try it out on a Python project:

$ interrogate [PATH]
RESULT: PASSED (minimum: 80.0%, actual: 100.0%)

Add verbosity to see a summary:

$ interrogate -v [PATH]

================== Coverage for /Users/lynn/dev/interrogate/ ====================
------------------------------------ Summary ------------------------------------
| Name                                  |   Total |   Miss |   Cover |   Cover% |
|---------------------------------------|---------|--------|---------|----------|
| src/interrogate/__init__.py           |       1 |      0 |       1 |     100% |
| src/interrogate/__main__.py           |       1 |      0 |       1 |     100% |
| src/interrogate/badge_gen.py          |       5 |      0 |       5 |     100% |
| src/interrogate/cli.py                |       2 |      0 |       2 |     100% |
| src/interrogate/config.py             |       8 |      0 |       8 |     100% |
| src/interrogate/coverage.py           |      25 |      0 |      25 |     100% |
| src/interrogate/utils.py              |      10 |      0 |      10 |     100% |
| src/interrogate/visit.py              |      16 |      0 |      16 |     100% |
| tests/functional/__init__.py          |       1 |      0 |       1 |     100% |
| tests/functional/test_cli.py          |       7 |      0 |       7 |     100% |
| tests/functional/test_coverage.py     |       6 |      0 |       6 |     100% |
| tests/unit/__init__.py                |       1 |      0 |       1 |     100% |
| tests/unit/test_badge_gen.py          |       6 |      0 |       6 |     100% |
| tests/unit/test_config.py             |      10 |      0 |      10 |     100% |
| tests/unit/test_utils.py              |      13 |      0 |      13 |     100% |
|---------------------------------------|---------|--------|---------|----------|
| TOTAL                                 |     112 |      0 |     112 |   100.0% |
---------------- RESULT: PASSED (minimum: 95.0%, actual: 100.0%) ----------------

Add even more verbosity:

$ interrogate -vv [PATH]

================== Coverage for /Users/lynn/dev/interrogate/ ====================
------------------------------- Detailed Coverage -------------------------------
| Name                                                                |  Status |
|---------------------------------------------------------------------|---------|
| src/interrogate/__init__.py (module)                                | COVERED |
|---------------------------------------------------------------------|---------|
| src/interrogate/__main__.py (module)                                | COVERED |
|---------------------------------------------------------------------|---------|
| src/interrogate/badge_gen.py (module)                               | COVERED |
|   save_badge (L33)                                                  | COVERED |
|   get_badge (L50)                                                   | COVERED |
|   get_color (L66)                                                   | COVERED |
|   create (L79)                                                      | COVERED |
|---------------------------------------------------------------------|---------|
| src/interrogate/cli.py (module)                                     | COVERED |
|   main (L218)                                                       | COVERED |
|---------------------------------------------------------------------|---------|
| src/interrogate/config.py (module)                                  | COVERED |
|   InterrogateConfig (L17)                                           | COVERED |
|   find_project_root (L52)                                           | COVERED |
|   find_project_config (L80)                                         | COVERED |
|   parse_pyproject_toml (L91)                                        | COVERED |
|   sanitize_list_values (L107)                                       | COVERED |
|   parse_setup_cfg (L130)                                            | COVERED |
|   read_config_file (L164)                                           | COVERED |
|---------------------------------------------------------------------|---------|
| src/interrogate/coverage.py (module)                                | COVERED |
|   BaseInterrogateResult (L21)                                       | COVERED |
|     BaseInterrogateResult.perc_covered (L35)                        | COVERED |
|   InterrogateFileResult (L49)                                       | COVERED |
|     InterrogateFileResult.combine (L62)                             | COVERED |
|   InterrogateResults (L76)                                          | COVERED |
|     InterrogateResults.combine (L88)                                | COVERED |
|   InterrogateCoverage (L96)                                         | COVERED |
|     InterrogateCoverage._add_common_exclude (L115)                  | COVERED |
|     InterrogateCoverage._filter_files (L122)                        | COVERED |
|     InterrogateCoverage.get_filenames_from_paths (L139)             | COVERED |
|     InterrogateCoverage._filter_nodes (L166)                        | COVERED |
|     InterrogateCoverage._get_file_coverage (L192)                   | COVERED |
|     InterrogateCoverage._get_coverage (L218)                        | COVERED |
|     InterrogateCoverage.get_coverage (L235)                         | COVERED |
|     InterrogateCoverage._get_filename (L240)                        | COVERED |
|     InterrogateCoverage._get_detailed_row (L251)                    | COVERED |
|     InterrogateCoverage._create_detailed_table (L268)               | COVERED |
|       InterrogateCoverage._create_detailed_table._sort_nodes (L275) | COVERED |
|     InterrogateCoverage._print_detailed_table (L297)                | COVERED |
|     InterrogateCoverage._create_summary_table (L315)                | COVERED |
|     InterrogateCoverage._print_summary_table (L349)                 | COVERED |
|     InterrogateCoverage._sort_results (L367)                        | COVERED |
|     InterrogateCoverage._get_header_base (L397)                     | COVERED |
|     InterrogateCoverage.print_results (L406)                        | COVERED |
|---------------------------------------------------------------------|---------|
| src/interrogate/utils.py (module)                                   | COVERED |
|   parse_regex (L22)                                                 | COVERED |
|   smart_open (L41)                                                  | COVERED |
|   get_common_base (L61)                                             | COVERED |
|   OutputFormatter (L81)                                             | COVERED |
|     OutputFormatter.should_markup (L91)                             | COVERED |
|     OutputFormatter.set_detailed_markup (L106)                      | COVERED |
|     OutputFormatter.set_summary_markup (L130)                       | COVERED |
|     OutputFormatter._interrogate_line_formatter (L159)              | COVERED |
|     OutputFormatter.get_table_formatter (L222)                      | COVERED |
|---------------------------------------------------------------------|---------|
| src/interrogate/visit.py (module)                                   | COVERED |
|   CovNode (L15)                                                     | COVERED |
|   CoverageVisitor (L42)                                             | COVERED |
|     CoverageVisitor._has_doc (L56)                                  | COVERED |
|     CoverageVisitor._visit_helper (L63)                             | COVERED |
|     CoverageVisitor._is_nested (L109)                               | COVERED |
|     CoverageVisitor._is_private (L118)                              | COVERED |
|     CoverageVisitor._is_semiprivate (L126)                          | COVERED |
|     CoverageVisitor._is_ignored_common (L136)                       | COVERED |
|     CoverageVisitor._has_property_decorators (L153)                 | COVERED |
|     CoverageVisitor._is_func_ignored (L167)                         | COVERED |
|     CoverageVisitor._is_class_ignored (L188)                        | COVERED |
|     CoverageVisitor.visit_Module (L192)                             | COVERED |
|     CoverageVisitor.visit_ClassDef (L199)                           | COVERED |
|     CoverageVisitor.visit_FunctionDef (L208)                        | COVERED |
|     CoverageVisitor.visit_AsyncFunctionDef (L217)                   | COVERED |
|---------------------------------------------------------------------|---------|
| tests/functional/__init__.py (module)                               | COVERED |
|---------------------------------------------------------------------|---------|
| tests/functional/test_cli.py (module)                               | COVERED |
|   runner (L22)                                                      | COVERED |
|   test_run_no_paths (L30)                                           | COVERED |
|   test_run_shortflags (L71)                                         | COVERED |
|   test_run_longflags (L97)                                          | COVERED |
|   test_run_multiple_flags (L115)                                    | COVERED |
|   test_generate_badge (L126)                                        | COVERED |
|---------------------------------------------------------------------|---------|
| tests/functional/test_coverage.py (module)                          | COVERED |
|   test_coverage_simple (L42)                                        | COVERED |
|   test_coverage_errors (L55)                                        | COVERED |
|   test_print_results (L83)                                          | COVERED |
|   test_print_results_ignore_module (L117)                           | COVERED |
|   test_print_results_single_file (L144)                             | COVERED |
|---------------------------------------------------------------------|---------|
| tests/unit/__init__.py (module)                                     | COVERED |
|---------------------------------------------------------------------|---------|
| tests/unit/test_badge_gen.py (module)                               | COVERED |
|   test_save_badge (L25)                                             | COVERED |
|   test_save_badge_windows (L47)                                     | COVERED |
|   test_get_badge (L61)                                              | COVERED |
|   test_get_color (L85)                                              | COVERED |
|   test_create (L102)                                                | COVERED |
|---------------------------------------------------------------------|---------|
| tests/unit/test_config.py (module)                                  | COVERED |
|   test_find_project_root (L29)                                      | COVERED |
|   test_find_project_config (L45)                                    | COVERED |
|   test_parse_pyproject_toml (L54)                                   | COVERED |
|   test_sanitize_list_values (L84)                                   | COVERED |
|   test_parse_setup_cfg (L89)                                        | COVERED |
|   test_parse_setup_cfg_raises (L114)                                | COVERED |
|   test_read_config_file_none (L125)                                 | COVERED |
|   test_read_config_file (L184)                                      | COVERED |
|   test_read_config_file_raises (L198)                               | COVERED |
|---------------------------------------------------------------------|---------|
| tests/unit/test_utils.py (module)                                   | COVERED |
|   test_parse_regex (L32)                                            | COVERED |
|   test_smart_open (L39)                                             | COVERED |
|   test_get_common_base (L69)                                        | COVERED |
|   test_get_common_base_windows (L100)                               | COVERED |
|   test_output_formatter_should_markup (L132)                        | COVERED |
|   test_output_formatter_set_detailed_markup (L163)                  | COVERED |
|   test_output_formatter_set_summary_markup (L206)                   | COVERED |
|   test_output_formatter_interrogate_line_formatter (L258)           | COVERED |
|   test_output_formatter_interrogate_line_formatter_windows (L319)   | COVERED |
|   test_output_formatter_get_table_formatter (L343)                  | COVERED |
|   test_output_formatter_get_table_formatter_py38 (L381)             | COVERED |
|   test_output_formatter_get_table_formatter_raises (L395)           | COVERED |
|---------------------------------------------------------------------|---------|

------------------------------------ Summary ------------------------------------
| Name                                  |   Total |   Miss |   Cover |   Cover% |
|---------------------------------------|---------|--------|---------|----------|
| src/interrogate/__init__.py           |       1 |      0 |       1 |     100% |
| src/interrogate/__main__.py           |       1 |      0 |       1 |     100% |
| src/interrogate/badge_gen.py          |       5 |      0 |       5 |     100% |
| src/interrogate/cli.py                |       2 |      0 |       2 |     100% |
| src/interrogate/config.py             |       8 |      0 |       8 |     100% |
| src/interrogate/coverage.py           |      25 |      0 |      25 |     100% |
| src/interrogate/utils.py              |      10 |      0 |      10 |     100% |
| src/interrogate/visit.py              |      16 |      0 |      16 |     100% |
| tests/functional/__init__.py          |       1 |      0 |       1 |     100% |
| tests/functional/test_cli.py          |       7 |      0 |       7 |     100% |
| tests/functional/test_coverage.py     |       6 |      0 |       6 |     100% |
| tests/unit/__init__.py                |       1 |      0 |       1 |     100% |
| tests/unit/test_badge_gen.py          |       6 |      0 |       6 |     100% |
| tests/unit/test_config.py             |      10 |      0 |      10 |     100% |
| tests/unit/test_utils.py              |      13 |      0 |      13 |     100% |
|---------------------------------------|---------|--------|---------|----------|
| TOTAL                                 |     112 |      0 |     112 |   100.0% |
---------------- RESULT: PASSED (minimum: 95.0%, actual: 100.0%) ----------------

Other Usage

Generate a shields.io badge (like this one! interrogate-badge ):

$ interrogate --generate-badge PATH
RESULT: PASSED (minimum: 80.0%, actual: 100.0%)
Generated badge to /Users/lynn/dev/interrogate/docs/_static/interrogate_badge.svg

Add it to your tox.ini file to enforce a level of coverage:

[testenv:doc]
deps = interrogate
skip_install = true
commands =
    interrogate --quiet --fail-under 95 src tests

Or use it with pre-commit:

repos:
  - repo: https://github.com/econchick/interrogate
    rev: 1.3.2  # or master if you're bold
    hooks:
      - id: interrogate
        args: [--quiet, --fail-under=95]

Use it within your code directly:

>>> from interrogate import coverage
>>> cov = coverage.InterrogateCoverage(paths=["src"])
>>> results = cov.get_coverage()
>>> results
InterrogateResults(total=68, covered=65, missing=3)

Use interrogate with GitHub Actions. Check out the action written & maintained by Jack McKew (thank you, Jack!).

Configuration

Configure within your pyproject.toml (interrogate will automatically detect a pyproject.toml file and pick up default values for the command line options):

$ interrogate -c pyproject.toml [OPTIONS] [PATHS]...
[tool.interrogate]
ignore-init-method = true
ignore-init-module = false
ignore-magic = false
ignore-semiprivate = false
ignore-private = false
ignore-property-decorators = false
ignore-module = false
fail-under = 95
exclude = ["setup.py", "docs", "build"]
ignore-regex = ["^get$", "^mock_.*", ".*BaseClass.*"]
verbose = 0
quiet = false
whitelist-regex = []
color = true

Or configure within your setup.cfg (interrogate will automatically detect a setup.cfg file and pick up default values for the command line options):

$ interrogate -c setup.cfg [OPTIONS] [PATHS]...
[tool:interrogate]
ignore-init-method = true
ignore-init-module = false
ignore-magic = false
ignore-semiprivate = false
ignore-private = false
ignore-property-decorators = false
ignore-module = false
fail-under = 95
exclude = setup.py,docs,build
ignore-regex = ^get$,^mock_.*,.*BaseClass.*
verbose = 0
quiet = false
whitelist-regex =
color = true

Warning

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.

To view all options available, run interrogate --help:

interrogate -h
Usage: interrogate [OPTIONS] [PATHS]...

  Measure and report on documentation coverage in Python modules.

Options:
  --version                       Show the version and exit.
  -v, --verbose                   Level of verbosity  [default: 0]
  -q, --quiet                     Do not print output  [default: False]
  -f, --fail-under INT | FLOAT    Fail when coverage % is less than a given
                                  amount.  [default: 80.0]

  -e, --exclude PATH              Exclude PATHs of files and/or directories.
                                  Multiple `-e/--exclude` invocations
                                  supported.

  -i, --ignore-init-method        Ignore `__init__` method of classes.
                                  [default: False]

  -I, --ignore-init-module        Ignore `__init__.py` modules.  [default:
                                  False]

  -m, --ignore-magic              Ignore all magic methods of classes.
                                  [default: False]

                                  NOTE: This does not include the `__init__`
                                  method. To ignore `__init__` methods, use
                                  `--ignore-init-method`.

  -M, --ignore-module             Ignore module-level docstrings.  [default:
                                  False]

  -n, --ignore-nested-functions   Ignore nested functions and methods.
                                  [default: False]

  -p, --ignore-private            Ignore private classes, methods, and
                                  functions starting with two underscores.
                                  [default: False]

                                  NOTE: This does not include magic methods;
                                  use `--ignore-magic` and/or `--ignore-init-
                                  method` instead.

  -P, --ignore-property-decorators
                                  Ignore methods with property setter/getter
                                  decorators.  [default: False]

  -s, --ignore-semiprivate        Ignore semiprivate classes, methods, and
                                  functions starting with a single underscore.
                                  [default: False]

  -r, --ignore-regex STR          Regex identifying class, method, and
                                  function names to ignore. Multiple
                                  `-r/--ignore-regex` invocations supported.

  -w, --whitelist-regex STR       Regex identifying class, method, and
                                  function names to include. Multiple
                                  `-w/--whitelist-regex` invocations
                                  supported.

  -o, --output FILE               Write output to a given FILE.  [default:
                                  stdout]

  --color / --no-color            Toggle color output on/off when printing to
                                  stdout.  [default: True]

  -g, --generate-badge PATH       Generate a 'shields.io' status badge (an SVG
                                  image) in at a given file or directory. Will
                                  not generate a badge if results did not
                                  change from an existing badge of the same
                                  path.

  -h, --help                      Show this message and exit.
  -c, --config FILE               Read configuration from `pyproject.toml` or
                                  `setup.cfg`.

Credits

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 (turtles...).

The cute sloth logo is by JustineW purchased via the Noun Project (but also available under the Creative Commons License with attribution).

Comments
  • ⬆️ UPGRADE: Autoupdate pre-commit config

    ⬆️ UPGRADE: Autoupdate pre-commit config

    Base PullRequest

    ⬆️ UPGRADE: Autoupdate pre-commit config (#54)

    Command results

    Details:
    add path
    /home/runner/work/_actions/technote-space/create-pr-action/v2/node_modules/npm-check-updates/bin
    
    pip install pre-commit
    Collecting pre-commit
      Downloading pre_commit-2.9.2-py2.py3-none-any.whl (184 kB)
    Collecting nodeenv>=0.11.1
      Downloading nodeenv-1.5.0-py2.py3-none-any.whl (21 kB)
    Collecting cfgv>=2.0.0
      Downloading cfgv-3.2.0-py2.py3-none-any.whl (7.3 kB)
    Collecting pyyaml>=5.1
      Downloading PyYAML-5.3.1.tar.gz (269 kB)
    Collecting virtualenv>=20.0.8
      Downloading virtualenv-20.2.1-py2.py3-none-any.whl (4.9 MB)
    Collecting identify>=1.0.0
      Downloading identify-1.5.10-py2.py3-none-any.whl (97 kB)
    Collecting toml
      Downloading toml-0.10.2-py2.py3-none-any.whl (16 kB)
    Collecting distlib<1,>=0.3.1
      Downloading distlib-0.3.1-py2.py3-none-any.whl (335 kB)
    Collecting six<2,>=1.9.0
      Downloading six-1.15.0-py2.py3-none-any.whl (10 kB)
    Collecting filelock<4,>=3.0.0
      Downloading filelock-3.0.12-py3-none-any.whl (7.6 kB)
    Collecting appdirs<2,>=1.4.3
      Downloading appdirs-1.4.4-py2.py3-none-any.whl (9.6 kB)
    Using legacy 'setup.py install' for pyyaml, since package 'wheel' is not installed.
    Installing collected packages: nodeenv, cfgv, pyyaml, distlib, six, filelock, appdirs, virtualenv, identify, toml, pre-commit
        Running setup.py install for pyyaml: started
        Running setup.py install for pyyaml: finished with status 'done'
    Successfully installed appdirs-1.4.4 cfgv-3.2.0 distlib-0.3.1 filelock-3.0.12 identify-1.5.10 nodeenv-1.5.0 pre-commit-2.9.2 pyyaml-5.3.1 six-1.15.0 toml-0.10.2 virtualenv-20.2.1
    
    pre-commit autoupdate || (exit 0);
    Updating https://github.com/psf/black ... updating 19.10b0 -> 20.8b1.
    Updating https://gitlab.com/pycqa/flake8 ... updating 3.7.9 -> 3.8.4.
    Updating https://github.com/pre-commit/mirrors-isort ... [INFO] Initializing environment for https://github.com/pre-commit/mirrors-isort.
    updating v4.3.21 -> v5.6.4.
    Updating https://github.com/pre-commit/pre-commit-hooks ... [INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
    updating v2.4.0 -> v3.3.0.
    
    pre-commit run -a || (exit 0);
    [INFO] Initializing environment for https://github.com/pre-commit/mirrors-isort:toml.
    [INFO] Installing environment for https://github.com/psf/black.
    [INFO] Once installed this environment will be reused.
    [INFO] This may take a few minutes...
    [INFO] Installing environment for https://gitlab.com/pycqa/flake8.
    [INFO] Once installed this environment will be reused.
    [INFO] This may take a few minutes...
    [INFO] Installing environment for https://github.com/pre-commit/mirrors-isort.
    [INFO] Once installed this environment will be reused.
    [INFO] This may take a few minutes...
    [INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
    [INFO] Once installed this environment will be reused.
    [INFO] This may take a few minutes...
    interrogate..............................................................Failed
    - hook id: interrogate
    - exit code: 1
    
    Executable `interrogate` not found
    
    black....................................................................Failed
    - hook id: black
    - files were modified by this hook
    
    reformatted /home/runner/work/interrogate/interrogate/setup.py
    reformatted /home/runner/work/interrogate/interrogate/src/interrogate/cli.py
    reformatted /home/runner/work/interrogate/interrogate/tests/functional/test_coverage.py
    reformatted /home/runner/work/interrogate/interrogate/tests/unit/test_config.py
    All done! ✨ 🍰 ✨
    4 files reformatted, 19 files left unchanged.
    
    flake8...................................................................Passed
    isort....................................................................Failed
    - hook id: isort
    - files were modified by this hook
    
    Fixing /home/runner/work/interrogate/interrogate/src/interrogate/cli.py
    Fixing /home/runner/work/interrogate/interrogate/src/interrogate/utils.py
    
    Trim Trailing Whitespace.................................................Passed
    Fix End of Files.........................................................Passed
    Debug Statements (Python)................................................Passed
    

    Changed files

    Changed 6 files:
    • .pre-commit-config.yaml
    • setup.py
    • src/interrogate/cli.py
    • src/interrogate/utils.py
    • tests/functional/test_coverage.py
    • tests/unit/test_config.py

    :octocat: Repo | :memo: Issues | :department_store: Marketplace

    opened by econchick 13
  • path exclusion in no longer os-dependent

    path exclusion in no longer os-dependent

    Hey, I just made a Pull Request!

    Description

    Excluding path is no longer os-dependent, by using os.path.normpath.

    Motivation and Context

    Fixes #51

    Have you tested this? If so, how?

    I ran interrogate with these changes over relevant cases and it works for me. No additional unit tests required.

    Checklist for PR author(s)

    • [x] Changes are covered by unit tests (no major decrease in code coverage %).
    • [X] All tests pass.
    • [X] Docstring coverage is 100% via tox -e docs or interrogate -c pyproject.toml (I mean, we should set a good example :smile:).
    • [X] Updates to documentation:
      • [X] Document any relevant additions/changes in README.rst.
      • [X] Manually update both the README.rst and docs/index.rst for any new/changed CLI flags.
      • [X] Any changed/added classes/methods/functions have appropriate versionadded, versionchanged, or deprecated directives. Find the appropriate next version in the project's __init__.py file.
    opened by oriash93 9
  • --skip-covered: Proof of concept

    --skip-covered: Proof of concept

    interrogate is great! I'm using it to check whether all unit tests have docstrings (not my idea) and it has been very helpful.

    I'm running it together with black, flake8 and isort (https://github.com/matthiask/workbench/blob/master/tox.ini). Currently there does not seem to be a way to make interrogate only show files where coverage isn't 100%. Without a -v it only shows the summary, with one -v it also shows all files with 100% coverage.

    This draft pull request adds a --skip-covered option (name and help text copied from coverage). Are you interested in this feature? If yes, do you see a better way to implement this? I don't want to drop a big pull request with tests and everything without starting a discussion first.

    opened by matthiask 8
  • Bug: `common_base` not found on Windows

    Bug: `common_base` not found on Windows

    First of all, I really like the intent of this package! 👍

    Is this a BUG REPORT or FEATURE REQUEST?:

    • [X] bug
    • [ ] feature

    Description of Bug or Feature

    Environment

    • interrogate version: 1.14
    • Operating System(s): Windows 10
    • Python version(s): 3.8

    What happened

    utils.get_common_base() does not find the common base for files on Windows.

    This happens because path levels are split by \\ in Python on Windows. As a result, the common_base is an empty string (""). This has a downstream effect when generating the summary tables.

    Specifically, in _get_filename(), since the common_base is an empty string, a filepath:

    C:\path\to\project_root\src\file.py

    becomes :\path\to\project_root\src\file.py

    instead of: \src\file.py

    Suggestion

    Since this is a python 3.5+ project, I think that this could be fixed in a flexible way by handling filepaths with pathlib instead. For example this in utils.py:

    level_slices = zip(*[f.split("/") for f in files])
    

    could be replaced with:

    from pathlib import Path
    level_slices = zip(*[Path(f).parts for f in files])
    

    (if file names had not already been converted to Path objects)

    Using pathlib here would help make this feature work across systems, but I think it could also replace just about all path manipulation interrogate uses os for.

    If you'd like I could work contributing to any of these proposed changes.

    bug 
    opened by hectormz 8
  • ⬆️ UPGRADE: Autoupdate pre-commit config

    ⬆️ UPGRADE: Autoupdate pre-commit config

    Base PullRequest

    default branch (https://github.com/econchick/interrogate/tree/master)

    Command results

    Details:
    add path
    /home/runner/work/_actions/technote-space/create-pr-action/v2/node_modules/npm-check-updates/bin
    
    pip install pre-commit
    Collecting pre-commit
      Downloading pre_commit-2.13.0-py2.py3-none-any.whl (190 kB)
    Collecting virtualenv>=20.0.8
      Downloading virtualenv-20.4.7-py2.py3-none-any.whl (7.2 MB)
    Collecting cfgv>=2.0.0
      Downloading cfgv-3.3.0-py2.py3-none-any.whl (7.3 kB)
    Collecting nodeenv>=0.11.1
      Downloading nodeenv-1.6.0-py2.py3-none-any.whl (21 kB)
    Collecting identify>=1.0.0
      Downloading identify-2.2.9-py2.py3-none-any.whl (98 kB)
    Collecting toml
      Downloading toml-0.10.2-py2.py3-none-any.whl (16 kB)
    Collecting pyyaml>=5.1
      Downloading PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl (630 kB)
    Collecting six<2,>=1.9.0
      Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)
    Collecting distlib<1,>=0.3.1
      Downloading distlib-0.3.2-py2.py3-none-any.whl (338 kB)
    Collecting appdirs<2,>=1.4.3
      Downloading appdirs-1.4.4-py2.py3-none-any.whl (9.6 kB)
    Collecting filelock<4,>=3.0.0
      Downloading filelock-3.0.12-py3-none-any.whl (7.6 kB)
    Installing collected packages: six, filelock, distlib, appdirs, virtualenv, toml, pyyaml, nodeenv, identify, cfgv, pre-commit
    Successfully installed appdirs-1.4.4 cfgv-3.3.0 distlib-0.3.2 filelock-3.0.12 identify-2.2.9 nodeenv-1.6.0 pre-commit-2.13.0 pyyaml-5.4.1 six-1.16.0 toml-0.10.2 virtualenv-20.4.7
    
    pre-commit autoupdate || (exit 0);
    Updating https://github.com/psf/black ... [INFO] Initializing environment for https://github.com/psf/black.
    updating 21.5b1 -> 21.5b2.
    Updating https://gitlab.com/pycqa/flake8 ... [INFO] Initializing environment for https://gitlab.com/pycqa/flake8.
    already up to date.
    Updating https://github.com/pre-commit/mirrors-isort ... [INFO] Initializing environment for https://github.com/pre-commit/mirrors-isort.
    already up to date.
    Updating https://github.com/pre-commit/pre-commit-hooks ... [INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
    already up to date.
    
    pre-commit run -a || (exit 0);
    [INFO] Initializing environment for https://github.com/pre-commit/mirrors-isort:toml.
    [INFO] Installing environment for https://github.com/psf/black.
    [INFO] Once installed this environment will be reused.
    [INFO] This may take a few minutes...
    [INFO] Installing environment for https://gitlab.com/pycqa/flake8.
    [INFO] Once installed this environment will be reused.
    [INFO] This may take a few minutes...
    [INFO] Installing environment for https://github.com/pre-commit/mirrors-isort.
    [INFO] Once installed this environment will be reused.
    [INFO] This may take a few minutes...
    [INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
    [INFO] Once installed this environment will be reused.
    [INFO] This may take a few minutes...
    interrogate..............................................................Failed
    - hook id: interrogate
    - exit code: 1
    
    Executable `interrogate` not found
    
    black....................................................................Passed
    flake8...................................................................Passed
    isort....................................................................Passed
    Trim Trailing Whitespace.................................................Passed
    Fix End of Files.........................................................Passed
    Debug Statements (Python)................................................Passed
    

    Changed files

    Changed file:
    • .pre-commit-config.yaml

    :octocat: Repo | :memo: Issues | :department_store: Marketplace

    opened by econchick 7
  • Use pathlib for file path management

    Use pathlib for file path management

    This PR uses pathlib for file path management, which should make cross-platform support easier.

    This PR resolves #15

    pathlib could be implemented to replace a lot of os usage elsewhere in the project, but this PR was focused on coverage.py.

    ATTN: @econchick

    The original tests don't run properly on Windows, but this was tested and run on Linux, where all tests passed.

    The default common_base = "" is now common_base = Path("/"). I'm not sure if this is fine with you, or if this breaks something in your use case.

    Tests were updated, but hopefully they still test the properties you intended.

    Let me know if there is anything that is not quite right, or some lines that could use some explanation. There are still some cases where a Path was converted into a str or where os was used. There may be a more elegant solution that I'm not familiar with.

    opened by hectormz 6
  • Fix for classifiers not being used in setup

    Fix for classifiers not being used in setup

    Description

    PyPI classifiers are defined here, but not actually used during setup, so they won't be displayed among metadata on PyPI.

    Motivation and Context

    Resolves #61

    opened by mmtj 5
  • Feature Request: Option to ignore nested functions

    Feature Request: Option to ignore nested functions

    Is this a BUG REPORT or FEATURE REQUEST?:

    • [ ] bug
    • [x] feature

    Description of Bug or Feature

    Nested functions (i.e. function definitions within function definitions) are usually small helpers that need no docstring and are not part of the public API. It should therefore be possible to optionally ignore them.

    enhancement 
    opened by torfsen 5
  • Add --skip-covered flag to disable reporting covered files

    Add --skip-covered flag to disable reporting covered files

    Describe the feature you'd like

    Interrogate's output can get very verbose which is very useful, however sometimes it would also be useful to ignore any files that are 100% covered to focus on the files that need docstrings added, I suggest adding a --skip-covered flag to disable reporting of such files.

    Is your feature request related to a problem?

    No

    Your Environment

    • interrogate version(s) (interrogate --version: version 1.4.0
    • Operating System(s): MacOS
    • Python version(s): 3.9

    Additional context

    Coverage.py supports skipping covered files

    enhancement 
    opened by RobertCraigie 4
  • Update tooling

    Update tooling

    Just some tooling additions that you might like.

    • Update actions/setup-python to V2
    • Added dependabot config to check for new github action version
    • Added pre-commit Ci check for quality assurence
    • Added workflow to autoupdate .pre-commit-config.yaml

    Description

    Changes since actions/setup-python@v1

    • Improved logs & output when downloading and setting up Python versions
    • Improvements and updates to downloading Python versions from actions/python-versions
    • Support for pre-release Python distributions
    • Fix installation logic to prevent leaving files in GITHUB_WORKSPACE
    • Ability to download python packages from actions/python-versions
    • Easy setup when using a self-hosted runner
    • Support for GHES

    For the pre-commit autoupdate workflow to work you need to set a secret ACTION_TRIGGER_TOKEN, which is an access token with repo or public_repo scope. This is needed in order for the action generated PR's to trigger the CI.

    Motivation and Context

    I saw that actions/setup-python was still at v1 and that some pre-commit repo revisions are outdated, so why not use the latest and greatest? 😄

    Have you tested this? If so, how?

    I'm using a similar/identical setup in my repos 😉

    opened by s-weigand 4
  • Make Badge newline configurable or only update if content changed

    Make Badge newline configurable or only update if content changed

    Describe the feature you'd like

    First of all thanks for the awesome tool 😄 I would love to use the badge creation feature as a pre-push hook in my projects, so the badge is always up to date. But since each major OS has its own newline (Linux \n, MacOs '\r' and Windows \r\n), creating a new badge on push can lead to a diff, which basically is empty, blocking the push. Since my projects (as most others I guess) are setup to have \n as newline, it would be nice to have badge_newline as a configurable option (this can be done with a kwarg in open).

    Alternative solution

    Another alternative would be to check if the text in interrogate_badge.svg did change and only write changes if that is the case. That way the new line cofiguration would be left to the user (i.e. via .gitattributes), an not clutter the CLI and config of interrogate.

    Is your feature request related to a problem?

    Badge creation blocks usage with pre-commit.

    Your Environment

    • interrogate version(s) (interrogate --version: 1.2.0
    • Operating System(s): Win10
    • Python version(s): 3.7.6
    enhancement 
    opened by s-weigand 4
  • Bump actions/cache from 3.0.5 to 3.2.1

    Bump actions/cache from 3.0.5 to 3.2.1

    Bumps actions/cache from 3.0.5 to 3.2.1.

    Release notes

    Sourced from actions/cache's releases.

    v3.2.1

    What's Changed

    Full Changelog: https://github.com/actions/cache/compare/v3.2.0...v3.2.1

    v3.2.0

    What's Changed

    New Contributors

    Full Changelog: https://github.com/actions/cache/compare/v3...v3.2.0

    v3.2.0-beta.1

    What's Changed

    v3.1.0-beta.3

    What's Changed

    • Bug fixes for bsdtar fallback, if gnutar not available, and gzip fallback, if cache saved using old cache action, on windows.

    Full Changelog: https://github.com/actions/cache/compare/v3.1.0-beta.2...v3.1.0-beta.3

    ... (truncated)

    Changelog

    Sourced from actions/cache's changelog.

    3.0.5

    • Removed error handling by consuming actions/cache 3.0 toolkit, Now cache server error handling will be done by toolkit. (PR)

    3.0.6

    • Fixed #809 - zstd -d: no such file or directory error
    • Fixed #833 - cache doesn't work with github workspace directory

    3.0.7

    • Fixed #810 - download stuck issue. A new timeout is introduced in the download process to abort the download if it gets stuck and doesn't finish within an hour.

    3.0.8

    • Fix zstd not working for windows on gnu tar in issues #888 and #891.
    • Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable SEGMENT_DOWNLOAD_TIMEOUT_MINS. Default is 60 minutes.

    3.0.9

    • Enhanced the warning message for cache unavailablity in case of GHES.

    3.0.10

    • Fix a bug with sorting inputs.
    • Update definition for restore-keys in README.md

    3.0.11

    • Update toolkit version to 3.0.5 to include @actions/core@^1.10.0
    • Update @actions/cache to use updated saveState and setOutput functions from @actions/core@^1.10.0

    3.1.0-beta.1

    • Update @actions/cache on windows to use gnu tar and zstd by default and fallback to bsdtar and zstd if gnu tar is not available. (issue)

    3.1.0-beta.2

    • Added support for fallback to gzip to restore old caches on windows.

    3.1.0-beta.3

    • Bug fixes for bsdtar fallback if gnutar not available and gzip fallback if cache saved using old cache action on windows.

    3.2.0-beta.1

    • Added two new actions - restore and save for granular control on cache.

    3.2.0

    • Released the two new actions - restore and save for granular control on cache

    3.2.1

    • Update @actions/cache on windows to use gnu tar and zstd by default and fallback to bsdtar and zstd if gnu tar is not available. (issue)
    • Added support for fallback to gzip to restore old caches on windows.
    • Added logs for cache version in case of a cache miss.
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Add flag to check class attributes for documentation

    Add flag to check class attributes for documentation

    Hi there,

    One thing currently not tested by the tool is class variables, i.e. class members or attributes. This is important when generating documentation from code.

    For example, both code snippets will have the same documentation coverage currently:

    class Controller:
        """
        The Starlite Controller class. Subclass this class to create 'view' like components and utilize OOP.
        """
    
        after_request: Optional["AfterRequestHandler"]
        after_response: Optional["AfterResponseHandler"]
        before_request: Optional["BeforeRequestHandler"]
        dependencies: Optional[Dict[str, "Provide"]]
        exception_handlers: Optional[Dict[Union[int, "Type[Exception]"], "ExceptionHandler"]]
        guards: Optional[List["Guard"]]
        middleware: Optional[List["Middleware"]]
        owner: "Router"
        parameters: Optional[Dict[str, "FieldInfo"]]
        path: str
        response_class: Optional["Type[Response]"]
        response_cookies: Optional[List["Cookie"]]
        response_headers: Optional[Dict[str, "ResponseHeader"]]
        tags: Optional[List[str]]
    
        ...
    
    class Controller:
        """
        The Starlite Controller class. Subclass this class to create 'view' like components and utilize OOP.
        """
    
        __slots__ = (
            "after_request",
            "after_response",
            "before_request",
            "dependencies",
            "exception_handlers",
            "guards",
            "middleware",
            "owner",
            "parameters",
            "path",
            "response_class",
            "response_cookies",
            "response_headers",
            "tags",
        )
    
        after_request: Optional["AfterRequestHandler"]
        """
            A sync or async function executed before a [Request][starlite.connection.Request] is passed to any route handler.
            If this function returns a value, the request will not reach the route handler, and instead this value will be used.
        """
        after_response: Optional["AfterResponseHandler"]
        """
            A sync or async function called after the response has been awaited.
            It receives the [Request][starlite.connection.Request] instance and should not return any values.
        """
        before_request: Optional["BeforeRequestHandler"]
        """
            A sync or async function called immediately before calling the route handler.
            It receives the [Request][starlite.connection.Request] instance and any
            non-`None` return value is used for the response, bypassing the route handler.
        """
        dependencies: Optional[Dict[str, "Provide"]]
        """
            A string/[Provider][starlite.provide.Provide] dictionary that maps dependency providers.
        """
        exception_handlers: Optional[Dict[Union[int, "Type[Exception]"], "ExceptionHandler"]]
        """
            A dictionary that maps handler functions to status codes and/or exception types.
        """
        guards: Optional[List["Guard"]]
        """
            A list of [Guard][starlite.types.Guard] callables.
        """
        middleware: Optional[List["Middleware"]]
        """
            A list of [Middleware][starlite.types.Middleware].
        """
        owner: "Router"
        """
            The [Router][starlite.router.Router] or [Starlite][starlite.app.Starlite] app that owns the controller.
            This value is set internally by Starlite and it should not be set when subclassing the controller.
        """
        parameters: Optional[Dict[str, "FieldInfo"]]
        """
            A mapping of [Parameter][starlite.params.Parameter] definitions available to all application paths.
        """
        path: str
        """
            A path fragment for the controller.
            All route handlers under the controller will have the fragment appended to them.
            If not set it defaults to '/'.
        """
        response_class: Optional["Type[Response]"]
        """
            A custom subclass of [starlite.response.Response] to be used as the default response
            for all route handlers under the controller.
        """
        response_cookies: Optional[List["Cookie"]]
        """
            A list of [Cookie](starlite.datastructures.Cookie] instances.
        """
        response_headers: Optional[Dict[str, "ResponseHeader"]]
        """
            A string keyed dictionary mapping [ResponseHeader][starlite.datastructures.ResponseHeader] instances.
        """
        tags: Optional[List[str]]
        """
            A list of string tags that will be appended to the schema of all route handlers under the controller.
        """
        ...
    
    enhancement needs triage 
    opened by Goldziher 0
  • Both class and __init__ documentation are required when they shouldnt be

    Both class and __init__ documentation are required when they shouldnt be

    Hiya,

    interrogate assumes I need to document both the class and its __init__ method. Yet this is not required by tooling usually and is actually considered an anti-pattern - the class constructor is equivalent to documenting the class and vice versa.

    That is, the tool requires something like this:

    class MyClass:
        """
        This is MyClass and it has a valid docstring.
        """
        def __init__(self, some_arg: int):
            """        
            Args:
                some_arg: an integer
            """
            ...
    

    Whereas the two examples below are in fact correct documentation that raises errors currently:

    class MyClass:
        def __init__(self, some_arg: int):
            """ 
                This is MyClass and it has a valid docstring.
                
                Args:
                    some_arg: an integer
            """
            ...
    

    OR:

    class MyClass:
        """
        This is MyClass and it has a valid docstring.
    
        Args:
            some_arg: an integer
        """
        def __init__(self, some_arg: int):
            ...
    

    There is a good exposition on this https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html, which states:

        The __init__ method may be documented in either the class level
        docstring, or as a docstring on the __init__ method itself.
    
        Either form is acceptable, but the two should not be mixed. Choose one
        convention to document the __init__ method and be consistent with it.
    
    bug needs triage 
    opened by Goldziher 0
  • Property deleter not being ignored

    Property deleter not being ignored

    Environment

    • interrogate version(s) (interrogate --version): 1.5.0
    • Operating System(s): macOS
    • Python version(s): 3.9.10

    Description of the bug

    With ignore-property-decorators set to true, a property deleter is not being ignored.

    What you expected to happen

    A property deleter should be ignored the same way a property getter and setter is.

    How to reproduce (as minimally and precisely as possible)

    class C:
        @property
        def x(self):
            return self._x
    
        @x.setter
        def x(self, value):
            self._x = value
    
        @x.deleter
        def x(self):
            del self._x
    
    bug needs triage 
    opened by ts-mk 1
  • re.error: nothing to repeat at position 0

    re.error: nothing to repeat at position 0

    Environment

    • interrogate version(s) (interrogate --version: interrogate, version 1.5.0
    • Operating System(s): Ubuntu 22.04 LTS
    • Python version(s): 3.10

    Description of the bug

    Interrogate throws an exception (re.error) on every command.

    Traceback (most recent call last): File "/home/id986507/.local/bin/interrogate", line 8, in <module> sys.exit(main()) File "/home/id986507/.local/lib/python3.10/site-packages/click/core.py", line 829, in __call__ return self.main(*args, **kwargs) File "/home/id986507/.local/lib/python3.10/site-packages/click/core.py", line 781, in main with self.make_context(prog_name, args, **extra) as ctx: File "/home/id986507/.local/lib/python3.10/site-packages/click/core.py", line 700, in make_context self.parse_args(ctx, args) File "/home/id986507/.local/lib/python3.10/site-packages/click/core.py", line 1048, in parse_args value, args = param.handle_parse_result(ctx, opts, args) File "/home/id986507/.local/lib/python3.10/site-packages/click/core.py", line 1630, in handle_parse_result value = invoke_param_callback(self.callback, ctx, self, value) File "/home/id986507/.local/lib/python3.10/site-packages/click/core.py", line 123, in invoke_param_callback return callback(ctx, param, value) File "/home/id986507/.local/lib/python3.10/site-packages/interrogate/utils.py", line 36, in parse_regex return [re.compile(v) for v in values] File "/home/id986507/.local/lib/python3.10/site-packages/interrogate/utils.py", line 36, in <listcomp> return [re.compile(v) for v in values] File "/usr/lib/python3.10/re.py", line 251, in compile return _compile(pattern, flags) File "/usr/lib/python3.10/re.py", line 303, in _compile p = sre_compile.compile(pattern, flags) File "/usr/lib/python3.10/sre_compile.py", line 764, in compile p = sre_parse.parse(p, flags) File "/usr/lib/python3.10/sre_parse.py", line 950, in parse p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0) File "/usr/lib/python3.10/sre_parse.py", line 443, in _parse_sub itemsappend(_parse(source, state, verbose, nested + 1, File "/usr/lib/python3.10/sre_parse.py", line 668, in _parse raise source.error("nothing to repeat", re.error: nothing to repeat at position 0

    What you expected to happen

    Check for documentation in files, the normal behavior

    How to reproduce (as minimally and precisely as possible)

    id986507@BHLCWG3:~/saf$ interrogate --generate-badge saf/badge.svg Traceback (most recent call last): File "/home/id986507/.local/bin/interrogate", line 8, in <module>

    Anthing else we need to know?

    bug needs triage 
    opened by Charlie-Root 0
  • Add support for explicitly interrogating .pyi files.

    Add support for explicitly interrogating .pyi files.

    In some cases, it may be useful to interrogate .pyi files (i.e.: when checking docstring coverage of native Pybind11 modules). Interrogate can parse these files, but refuses to due to a file extension check.

    This PR adds a quick patch to work around the issue, while also fixing a typo in an error message. Note that this will not automatically pick up .pyi files in directory trees; .pyi files will only be parsed when passed explicitly to interrogate as filenames.

    opened by psobot 0
Owner
Lynn Root
Staff Engineer @spotify, @pyladies leader; @roguelynn on Twitter.
Lynn Root
📖 Generate markdown API documentation from Google-style Python docstring. The lazy alternative to Sphinx.

lazydocs Generate markdown API documentation for Google-style Python docstring. Getting Started • Features • Documentation • Support • Contribution •

Machine Learning Tooling 118 Dec 31, 2022
A simple malware that tries to explain the logic of computer viruses with Python.

Simple-Virus-With-Python A simple malware that tries to explain the logic of computer viruses with Python. What Is The Virus ? Computer viruses are ma

Xrypt0 6 Nov 18, 2022
Near Zero-Overhead Python Code Coverage

Slipcover: Near Zero-Overhead Python Code Coverage by Juan Altmayer Pizzorno and Emery Berger at UMass Amherst's PLASMA lab. About Slipcover Slipcover

PLASMA @ UMass 325 Dec 28, 2022
Docov - Light-weight, recursive docstring coverage analysis for python modules

docov Light-weight, recursive docstring coverage analysis for python modules. Ov

Richard D. Paul 3 Feb 4, 2022
Generates a coverage badge using coverage.py and the shields.io service.

Welcome to README Coverage Badger ?? Generates a coverage badge using coverage.py and the shields.io service. Your README file is then updated with th

Victor Miti 10 Dec 6, 2022
docstring style checker

pydocstyle - docstring style checker pydocstyle is a static analysis tool for checking compliance with Python docstring conventions. pydocstyle suppor

Python Code Quality Authority 982 Jan 3, 2023
A python documentation linter which checks that the docstring description matches the definition.

Darglint A functional docstring linter which checks whether a docstring's description matches the actual function/method implementation. Darglint expe

Terrence Reilly 463 Dec 31, 2022
📖 Generate markdown API documentation from Google-style Python docstring. The lazy alternative to Sphinx.

lazydocs Generate markdown API documentation for Google-style Python docstring. Getting Started • Features • Documentation • Support • Contribution •

Machine Learning Tooling 118 Dec 31, 2022
Type Persian without confusing words for yourself and others, in Adobe Connect

About In the Adobe Connect chat section, to type in Persian or Arabic, the written words will be confused and will be written and sent illegibly (This

Matin Najafi 23 Nov 26, 2021
Propagate Yourself: Exploring Pixel-Level Consistency for Unsupervised Visual Representation Learning, CVPR 2021

Propagate Yourself: Exploring Pixel-Level Consistency for Unsupervised Visual Representation Learning By Zhenda Xie*, Yutong Lin*, Zheng Zhang, Yue Ca

Zhenda Xie 293 Dec 20, 2022
Purge your likes and wall comments from VKontakte. Set yourself free from your digital footprint.

vk_liberator Regain liberty in the cruel social media world. This program assists you with purging your metadata from Russian social network VKontakte

null 20 Jun 11, 2021
A python script to prefab your scripts/text files, and re create them with ease and not have to open your browser to copy code or write code yourself

Scriptfab - What is it? A python script to prefab your scripts/text files, and re create them with ease and not have to open your browser to copy code

DevNugget 3 Jul 28, 2021
🎃 Some spooky code samples to hack yourself a pumpkin 👻

?? Tech Or Treat ?? It's spooky season for those who celebrate Halloween, and to get in the spirit (spirit - get it? ?? ) we thought it would be fun t

Jim Bennett 5 Feb 7, 2022
Fun program to overlay a mask to yourself using a webcam

Superhero Mask Overlay Description Simple project made for fun. It consists of placing a mask (a PNG image with transparent background) on your face.

KB Kwan 10 Dec 1, 2022
Analyse the limit order book in seconds. Zoom to tick level or get yourself an overview of the trading day.

Analyse the limit order book in seconds. Zoom to tick level or get yourself an overview of the trading day. Correlate the market activity with the Apple Keynote presentations.

null 2 Jan 4, 2022
Stop ask your soraka to ult you, just ult yourself

Lollo's auto-ultimate script Are you tired of your low elo friend who can't ult you with soraka when you ask for it? Use Useless Support and just ult

null 9 Oct 20, 2022
A simple message content sniping Discord bot which you can run yourself! Sniping API pulled from isobot and Arch bot

Discord Snipe Bot This is a bot made with the same message content sniping API from isobot and Arch bot. It's default prefix is -, however you can als

notsniped 5 Aug 11, 2022
A game theoretic approach to explain the output of any machine learning model.

SHAP (SHapley Additive exPlanations) is a game theoretic approach to explain the output of any machine learning model. It connects optimal credit allo

Scott Lundberg 18.3k Jan 8, 2023
L2X - Code for replicating the experiments in the paper Learning to Explain: An Information-Theoretic Perspective on Model Interpretation.

L2X Code for replicating the experiments in the paper Learning to Explain: An Information-Theoretic Perspective on Model Interpretation at ICML 2018,

Jianbo Chen 113 Sep 6, 2022
ELI5 is a Python package which helps to debug machine learning classifiers and explain their predictions

A library for debugging/inspecting machine learning classifiers and explaining their predictions

null 154 Dec 17, 2022