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

Add support for attribute docstring in the semantic model #11315

Merged
merged 2 commits into from
May 10, 2024

Conversation

dhruvmanila
Copy link
Member

@dhruvmanila dhruvmanila commented May 7, 2024

Summary

This PR adds updates the semantic model to detect attribute docstring.

Refer to PEP 258 for the definition of an attribute docstring.

This PR doesn't add full support for it but only considers string literals as attribute docstring for the following cases:

  1. A string literal following an assignment statement in the global scope.
  2. A global class attribute

For an assignment statement, it's considered an attribute docstring only if the target expression is a name expression (x = 1). So, chained assignment, multiple assignment or unpacking, and starred expression, which are all valid in the target position, aren't considered here.

In __init__ method, an assignment to the self variable like self.x = 1 is also a candidate for an attribute docstring. This PR does not support this position.

Test Plan

I used the following source code along with a print statement to verify that the attribute docstring detection is correct.

Source code to test against:

a: int
"a: docstring"

b = 1
"b docstring" " continue"
"b: not a docstring"

c: int = 1
"c: docstring"

_a: int
"_a: docstring"

if True:
    d = 1
    "d: not a docstring"

(e := 1)
"e: not a docstring"

f = 0
f += 1
"f: not a docstring"

g.h = 1
"g.h: not a docstring"

(i) = 1
"i: docstring"

(j): int = 1
"j: docstring"

(k): int
"k: docstring"

l = m = 1
"l m: not a docstring"

n.a = n.b = n.c = 1
"n.*: not a docstring"

(o, p) = (1, 2)
"o p: not a docstring"

[q, r] = [1, 2]
"q r: not a docstring"

*s = 1
"s: not a docstring"


class Foo:
    a = 1
    "Foo.a: docstring"

    b: int
    "Foo.b: docstring"
    "Foo.b: not a docstring"

    c: int = 1
    "Foo.c: docstring"

    def __init__(self) -> None:
        self.x = 1
        "self.x: docstring"

        t = 2
        "t: not a docstring"

    def random(self):
        self.y = 2
        "self.y: not a docstring"

        u = 2
        "u: not a docstring"

    def add(self, y: int):
        self.x += y


def function():
    v = 2
    "v: not a docstring"


function.a = 1
"function.a: not a docstring"

I'll add this in the follow-up PR (#11302) which uses this method.

@dhruvmanila dhruvmanila added internal An internal refactor or improvement linter Related to the linter labels May 7, 2024
Copy link
Contributor

github-actions bot commented May 7, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@dhruvmanila dhruvmanila marked this pull request as ready for review May 10, 2024 11:19
crates/ruff_python_semantic/src/model.rs Outdated Show resolved Hide resolved
crates/ruff_python_semantic/src/model.rs Show resolved Hide resolved
@dhruvmanila dhruvmanila removed the linter Related to the linter label May 10, 2024
@dhruvmanila dhruvmanila merged commit f79c980 into main May 10, 2024
19 checks passed
@dhruvmanila dhruvmanila deleted the dhruv/attribute-docstring branch May 10, 2024 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internal An internal refactor or improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants