-
Notifications
You must be signed in to change notification settings - Fork 17.5k
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
proposal: cmd/vet: add new flag to support stdmethod checks for specific methods #52445
Comments
See also #36970. This is roughly the same but a different function. An alternative is to rename the methods. This is not ideal, but it does work.
This is a reasonable mechanism for suppression. There would be a requirement that the assignment appears in the declaring package. There would also need to be a suppression mechanism for the warning on the interface definition. A possible mechanism could again be an assignment:
IMO changing the interface of stdmethods to allow for suppression [mechanism aside] goes against my intuition of 'if it passes cmd/vet [stdmethods], then if I see name a method named M, M has signature S [and implements standard interface I]'. I think this is a sufficiently large interface change to cmd/vet to require a proposal. Instructions on the proposal process: https://github.com/golang/proposal#the-proposal-process.
Would this effectively require that interfaces embed standard interfaces for interface definitions to be checked by stdmethods? That would be turning off checking for pre-existing interfaces if they contain the same function but do not embed the interface. This would also be true going forward. (Is this different than just type-checking at this point?) |
No. What I'm suggesting is by default it still checks everything (the current behavior), just allow explicit suppression. |
Thank you for the clarification. If I now understand correctly, this can be read as 'If not suppressed, keep the pre-existing check'? |
correct |
Thinking out loud about yet more options:
|
You can run vet by hand with |
We are already using I also disagree with the title change. This is a false positive with any stdmethods functions, not just |
I have partially reverted the title. If none of the suggested paths forward is appealing, I think the next step is to put forward a proposal for a suppression mechanism for this checker. A community contribution would be welcomed here. |
As @timothy-king mentioned, the suggested mechanism may be insufficient since the interface declaration alone
will trigger the warnings:
Basically checker stdmethods disallows reusing these method names with different signatures. On one hand, it is too strong since it uses only the method names to do matching. On the other hand, it is guessing that people are using these methods in a standard manner, and it is right in most cases. Instead of introducing a complicated suppression mechanism, I would suggest a simple one that allows people to define the subset of method names that should be checked or skipped checking, as checker printf does. |
I think the anonymous interface way as proposed by @timothy-king should work? e.g. var _ interface{WriteByte(ctx context.Context, value int8) error} = TProtocol(nil) but adding a flag to |
I guess @guodongli-google point is that the current implementation of the checker would still complain as there is a definition of interface
I agree a deny list seems a better fit here as the checker already has a predefined set of methods+signatures it looks at. Either way, this will likely require a proposal IMO. |
yea I will write a proposal when I get time 😅 |
Following the guidance of https://go.dev/s/proposal-process, I'm adding From the discussions above, the proposal is to: Add a command line flag to As a concrete example, for Apache Thrift go library, we should be able to run A few (half) open questions/rationales:
I think a denylist works much better here, as it allows users to suppress certain functions they know stdmethods will complain about otherwise (e.g. they know they are implementing some other interfaces with different expectations). If we use an allowlist instead, users are subject to add new methods to the allowlist when future version of
I initially tried to write this proposal with suppression from the code approach, as suggested in #52445 (comment), but as I wrote that proposal I realized that there are too many corner cases and potential breaking changes in that approach to make it far less feasible than the flag approach. For example, currently stdmethods will also complain unexpected function signatures in anonymous interfaces, so this needs to be changed (at least we need to make stdmethods to stop complaining on anonymous interfaces when the anonymous interface is used in a blank variable declaration case). |
oh wait actually I don't have the permissions to add |
I turned this issue into a proposal. Thanks. |
In the case of vet's printf checker we have been able to avoid the need for external configuration files by using Go declarations themselves to enable or disable the checker (with a comment to make the intent clear). This has several advantages:
I wonder whether a similar approach could be made to work here. In other words, is there some Go syntax we could add to the declaration of TProtocol that would have no effect at runtime but would indicate to the stdmethods analyzer (suitably modified) that TProtocol is exempt from the check. Here's a (very weak) starting point for illustration:
I imagine a number of other vet checks might want similar ways of expressing a set of types, or functions, or whatever, so we should examine them holistically before committing to any particular syntax. See also #58340 (comment) |
Change https://go.dev/cl/489835 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
In Apache Thrift go library, the interface
TProtocol
hasReadByte
andWriteByte
that's different from the expectation ofstdmethods
:This causes
go vet
to complain about the implementations, and we have to do extra work to disablestdmethods
check for packages containing the implementation, for example: https://github.com/reddit/baseplate.go/blob/205ac6852ad82ad5508106a6cb7156e2e73d3b3a/scripts/linters.sh#L19-L31IMHO the
stdmethods
check should auto skip "violations" that explicitly implement a different interface (e.g. this line ofvar _ thrift.TProtocol = (*tDuplicateToProtocol)(nil)
should be enough to silentstdmethods
on(*tDuplicateToProtocol).ReadByte
and(*tDuplicateToProtocol).WriteByte
), as an explicit interface with different function signature should be enough signal that the difference is intentional, otherwise the interface should embedio.ByteReader
/io.ByteWriter
instead.What did you expect to see?
What did you see instead?
The text was updated successfully, but these errors were encountered: