Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/pep8ext_naming.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,13 +537,14 @@ def visit_module(self, node, parents: Sequence, ignored: NameSet):
if func_name != "TypeVar" or name in ignored:
continue

if len(args) == 0 or args[0] != name:
if not args or args[0] != name:
yield self.err(body, 'N808', name=name)

if not name[:1].isupper():
stripped_name = name.lstrip('_')
Copy link
Member

Choose a reason for hiding this comment

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

I think the simplicity here is the attractive nuisance. I would probably bail on if name.startswith("__") because again, what's being asked for in the original issue is a single leading underscore. Double leading underscores for this are something I think we should draw a firm line in the sand about. I also don't agree with _T_co but am fine supporting it if someone can justify why they want a typevar that starts like that (aside from they're telling people to from <mod> import * which is just a bad reason to justify this).

I think we can simplify a lot of this logic though, because in retrospect, we can do

if name.startswith('__'):
    yield self.err(body, 'N808', name=name) # Maybe return to short-circuit things?

stripped_name = name.lstrip('_')
parts = stripped_name.rsplit('_', 1)
if not parts[0].istitle():
    yield self.err(body, 'N808', name=name)

# etc.

I don't think the __ is ever something we should not alert on frankly. It causes lots of silly magical things in the background.

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 also have some other overall improvements to this function that I'll save for another pull request.

if not stripped_name[:1].isupper():
yield self.err(body, 'N808', name=name)

parts = name.split('_')
parts = stripped_name.split('_')
if len(parts) > 2:
yield self.err(body, 'N808', name=name)

Expand Down
4 changes: 2 additions & 2 deletions testsuite/N808.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
#: Okay
Good = TypeVar("Good")

#: N808
__NotGood = TypeVar("__NotGood")
#: Okay
__Good = TypeVar("__Good")
Copy link
Member

Choose a reason for hiding this comment

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

I disagree. I believe _T_co is fine, or _T, but I don't believe __T (double underscore) is a good example here.

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
__Good = TypeVar("__Good")
_Good = TypeVar("_Good")
#: N808
__NotGood = TypeVar("__NotGood")

Copy link
Member Author

@jparise jparise May 1, 2025

Choose a reason for hiding this comment

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

I don't have strong feelings either way. I haven't had a case (personally) where I would use a leading underscore, but it appears others do this fairly often:

https://github.com/search?q=lang%3Apython+%22%3D+TypeVar%28%27_%22+OR+%22%3D+TypeVar%28%5C%22_%22&type=code

Leading double underscores exist but are uncommon, so I think that's a good argument against supporting them:

https://github.com/search?q=lang%3Apython+%22%3D+TypeVar%28%27__%22+OR+%22%3D+TypeVar%28%5C%22__%22&type=code


#: N808
__NotGood__ = TypeVar("__NotGood__")
Expand Down