Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Aug 2, 2024

Conversation

AlexWaygood
Copy link
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
Copy link
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
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
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
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 merged commit daccb3f into main Aug 2, 2024
20 checks passed
@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