Skip to content

[pydoclint] Deduplicate collected exceptions after traversing function bodies#12642

Merged
AlexWaygood merged 1 commit intomainfrom
alex/dedupe-pydoclint
Aug 2, 2024
Merged

[pydoclint] Deduplicate collected exceptions after traversing function bodies#12642
AlexWaygood merged 1 commit intomainfrom
alex/dedupe-pydoclint

Conversation

@AlexWaygood
Copy link
Copy Markdown
Member

Summary

I noticed when looking through the ecosystem report for #12639 that a function like this will be flagged twice for not stating in its docstring that it raises TypeError. We probably only need to emit one DOC501 violation for such a function:

def foo():
    """Foo.

    Returns:
        42: int
    """
    raise TypeError
    raise TypeError
    return 42

Test Plan

cargo test -p ruff_linter

@AlexWaygood AlexWaygood added rule Implementing or modifying a lint rule docstring Related to docstring linting or formatting preview Related to preview mode features labels Aug 2, 2024
@AlexWaygood AlexWaygood force-pushed the alex/dedupe-pydoclint branch from 57d7cbc to 1b4529b Compare August 2, 2024 19:03
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Aug 2, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+3 -644 violations, +0 -0 fixes in 4 projects; 50 projects unchanged)

apache/airflow (+3 -437 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

- airflow/api/common/experimental/__init__.py:43:15: DOC501 Raised exception `DagNotFound` missing from docstring
- airflow/api/common/experimental/pool.py:66:15: DOC501 Raised exception `AirflowBadRequest` missing from docstring
- airflow/api/common/experimental/pool.py:71:15: DOC501 Raised exception `AirflowBadRequest` missing from docstring
- airflow/api/common/experimental/pool.py:95:15: DOC501 Raised exception `AirflowBadRequest` missing from docstring
- airflow/api/common/mark_tasks.py:127:15: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api/common/mark_tasks.py:131:15: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api/common/mark_tasks.py:134:15: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api/common/mark_tasks.py:139:15: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api/common/mark_tasks.py:410:19: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api/common/mark_tasks.py:413:15: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api/common/mark_tasks.py:463:19: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api/common/mark_tasks.py:467:15: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api/common/mark_tasks.py:554:19: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api/common/mark_tasks.py:557:15: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api/common/trigger_dag.py:70:19: DOC501 Raised exception `ValueError` missing from docstring
- airflow/api_connexion/endpoints/connection_endpoint.py:140:15: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/connection_endpoint.py:169:15: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/dag_endpoint.py:154:19: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/dag_endpoint.py:178:19: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/dag_parsing.py:56:15: DOC501 Raised exception `NotFound` missing from docstring
- airflow/api_connexion/endpoints/dag_run_endpoint.py:318:15: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/dag_run_endpoint.py:361:19: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/dag_run_endpoint.py:371:11: DOC501 Raised exception `AlreadyExists` missing from docstring
- airflow/api_connexion/endpoints/dataset_endpoint.py:354:15: DOC501 Raised exception `NotFound` missing from docstring
- airflow/api_connexion/endpoints/extra_link_endpoint.py:58:15: DOC501 Raised exception `NotFound` missing from docstring
- airflow/api_connexion/endpoints/extra_link_endpoint.py:69:15: DOC501 Raised exception `NotFound` missing from docstring
- airflow/api_connexion/endpoints/log_endpoint.py:78:15: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/pool_endpoint.py:111:15: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/pool_endpoint.py:127:19: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/pool_endpoint.py:135:19: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/pool_endpoint.py:156:15: DOC501 Raised exception `BadRequest` missing from docstring
- airflow/api_connexion/endpoints/task_endpoint.py:44:15: DOC501 Raised exception `NotFound` missing from docstring
- airflow/api_connexion/endpoints/task_instance_endpoint.py:105:15: DOC501 Raised exception `NotFound` missing from docstring
- airflow/api_connexion/endpoints/task_instance_endpoint.py:107:15: DOC501 Raised exception `NotFound` missing from docstring
... 406 additional changes omitted for project

apache/superset (+0 -70 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

- superset/commands/database/uploaders/base.py:129:19: DOC501 Raised exception `DatabaseUploadFailed` missing from docstring
- superset/commands/database/uploaders/columnar_reader.py:102:23: DOC501 Raised exception `DatabaseUploadFailed` missing from docstring
- superset/commands/database/uploaders/columnar_reader.py:89:23: DOC501 Raised exception `DatabaseUploadFailed` missing from docstring
- superset/commands/database/uploaders/columnar_reader.py:95:31: DOC501 Raised exception `DatabaseUploadFailed` missing from docstring
- superset/commands/database/uploaders/excel_reader.py:94:19: DOC501 Raised exception `DatabaseUploadFailed` missing from docstring
- superset/commands/importers/v1/utils.py:74:19: DOC501 Raised exception `IncorrectVersionError` missing from docstring
- superset/commands/report/execute.py:272:19: DOC501 Raised exception `ReportScheduleScreenshotFailedError` missing from docstring
- superset/common/query_object.py:438:23: DOC501 Raised exception `InvalidPostProcessingError` missing from docstring
- superset/connectors/sqla/utils.py:119:15: DOC501 Raised exception `SupersetSecurityException` missing from docstring
- superset/daos/tag.py:95:19: DOC501 Raised exception `NoResultFound` missing from docstring
... 60 additional changes omitted for project

bokeh/bokeh (+0 -65 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

- src/bokeh/application/handlers/directory.py:153:19: DOC501 Raised exception `ValueError` missing from docstring
- src/bokeh/client/connection.py:215:19: DOC501 Raised exception `RuntimeError` missing from docstring
- src/bokeh/client/connection.py:235:19: DOC501 Raised exception `RuntimeError` missing from docstring
- src/bokeh/client/session.py:415:23: DOC501 Raised exception `OSError` missing from docstring
- src/bokeh/client/session.py:416:19: DOC501 Raised exception `OSError` missing from docstring
- src/bokeh/command/util.py:135:15: DOC501 Raised exception `ValueError` missing from docstring
- src/bokeh/core/enums.py:239:15: DOC501 Raised exception `ValueError` missing from docstring
- src/bokeh/core/property/descriptors.py:329:19: DOC501 Raised exception `RuntimeError` missing from docstring
- src/bokeh/core/property/descriptors.py:758:19: DOC501 Raised exception `RuntimeError` missing from docstring
- src/bokeh/core/validation/check.py:217:19: DOC501 Raised exception `RuntimeError` missing from docstring
... 55 additional changes omitted for project

zulip/zulip (+0 -72 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

- analytics/lib/fixtures.py:58:15: DOC501 Raised exception `AssertionError` missing from docstring
- confirmation/models.py:103:15: DOC501 Raised exception `ConfirmationKeyError` missing from docstring
- confirmation/models.py:106:15: DOC501 Raised exception `ConfirmationKeyError` missing from docstring
- confirmation/models.py:116:15: DOC501 Raised exception `ConfirmationKeyError` missing from docstring
- confirmation/models.py:307:15: DOC501 Raised exception `InvalidError` missing from docstring
- corporate/views/remote_billing_page.py:217:15: DOC501 Raised exception `JsonableError` missing from docstring
- corporate/views/remote_billing_page.py:299:15: DOC501 Raised exception `JsonableError` missing from docstring
- corporate/views/remote_billing_page.py:304:15: DOC501 Raised exception `JsonableError` missing from docstring
- zerver/actions/invites.py:165:19: DOC501 Raised exception `InvitationError` missing from docstring
- zerver/actions/message_edit.py:108:19: DOC501 Raised exception `JsonableError` missing from docstring
... 62 additional changes omitted for project

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
DOC501 647 3 644 0 0

});
raised_exceptions.dedup_by(|left, right| {
left.qualified_name.segments() == right.qualified_name.segments()
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use a BTreeSet instead, to get this for free?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, because we're storing ExceptionEntry objects in the Vec rather than QualifiedNames. ExceptionEntrys have two fields — one is a QualifiedName and the other is a TextRange. We want to make sure that no two ExceptionEntrys in the Vec have the same QualifiedName, regardless of whether they have the same TextRange or not

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible to do this by implementing Hash for ExceptionEntry manually, and omitting TextRange. But probably not worth it, can create confusion.

@AlexWaygood AlexWaygood force-pushed the alex/dedupe-pydoclint branch from 1b4529b to 0907b72 Compare August 2, 2024 21:55
@AlexWaygood AlexWaygood merged commit daccb3f into main Aug 2, 2024
@AlexWaygood AlexWaygood deleted the alex/dedupe-pydoclint branch August 2, 2024 22:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docstring Related to docstring linting or formatting preview Related to preview mode features rule Implementing or modifying a lint rule

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants