strip-hints
strip-hints copied to clipboard
Strip Protocol classes
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
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
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.
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:
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.
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.
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