strip-hints icon indicating copy to clipboard operation
strip-hints copied to clipboard

Strip Protocol classes

Open d3dave opened this issue 4 years ago • 5 comments

When encountering typing.Protocol classes, strip-hints doesn't strip the class definition, resulting in invalid syntax:

class Style(Protocol):
    #color: str
    #effect: str

which raises IndentationError: expected an indented block

d3dave avatar Oct 11 '21 16:10 d3dave

This is also a problem for typing.NamedTuple, which doesn't have as clean of a solution. However, I've come up with a simple fix which just prepends pass to the line so there aren't any indentation problems: https://github.com/abarker/strip-hints/pull/21

ava-silver avatar Feb 12 '25 21:02 ava-silver

That's a clever solution. Does it also work for typing.NamedTuple or are you saying that there's still an issue there?

Presumably the method would still work if only the first occurrence in a class had pass prepended.

abarker avatar Feb 16 '25 01:02 abarker

There's still an issue there, since typing.NamedTuple declared as a class requires these type declarations, so commenting them out at all means it doesn't have any fields. Unfortunately, you also can't just remove the type annotations there, since otherwise you'll get a NameError:

Image

The only real solution for NamedTuple would be fully rewriting the definition as a collections.namedtuple or using the functional syntax as mentioned in the docs:

import typing, collections
Employee = typing.NamedTuple('Employee', [('name', str), ('id', int)])
Employee = collections.namedtuple('Employee', ['name', 'id'])

Based on a cursory look at how the code is currently written, I don't see a great way to do this without a bit of a refactor, since it would require some backtracking or carving out specific cases for NamedTuple.

Also worth noting the same problem exists for dataclasses:

from dataclasses import dataclass
@dataclass
class Point:
    x: int
    y: int

I don't imagine this tool was not intended to perfectly preserve code, since python annotations are part of the code and can be used/seen at runtime, and as such removing annotations does not fully create equivalent code.

ava-silver avatar Feb 16 '25 01:02 ava-silver

I merged the fix for Protocol classes.

The dataclass classes and the class form of NamedTuple seem to inherently depend on the typing mechanism. I agree that it would probably require a rewrite of those code segments to maintain the runtime semantics.

abarker avatar Feb 18 '25 00:02 abarker

I just pushed out version 0.1.13. Any comment line that starts with # strip-hints: off will turn off stripping until another comment line that starts with # strip-hints: on. Examples:

@dataclass
class Point:
    # strip-hints: off
    x: int
    y: int
    # strip-hints: on

# strip-hints: off
@dataclass
class Point:
    x: int
    y: int
# strip-hints: on

abarker avatar Feb 21 '25 01:02 abarker