-
Notifications
You must be signed in to change notification settings - Fork 18k
text/template: Invalid handling off typed nils in if and with #30501
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
Comments
The However, The difference you're seeing here is due to the fact that Go implicitly converts a |
CC @mvdan, but I'm pretty sure this is working as documented. ( |
I will have a proper look soon, just not today. |
Before this commit, the two logically equivalent conditionals below would produce different output: ``` {{ if not .NonEmptyInterfaceTypedNil }}OK{{ else }}{{ end }} {{ if .NonEmptyInterfaceTypedNil }}{{ else }}OK{{ end }} ``` The functions `not`, `or`, and `and` all use the same `truth` function, which unwraps any concrete interface value before passing it to ´isTrue`. `if` and `with` also use `isTrue` to establish truth, but was missing the interface indirect call. Fixes golang#30501
Before this commit, the two logically equivalent conditionals below would produce different output: ``` {{ if not .NonEmptyInterfaceTypedNil }}OK{{ else }}{{ end }} {{ if .NonEmptyInterfaceTypedNil }}{{ else }}OK{{ end }} ``` The functions `not`, `or`, and `and` all use the same `truth` function, which unwraps any concrete interface value before passing it to `isTrue`. `if` and `with` also use `isTrue` to establish truth, but was missing the interface indirect call. Fixes golang#30501
Change https://golang.org/cl/164958 mentions this issue: |
Before this commit, the two logically equivalent conditionals below would produce different output: {{ if not .NonEmptyInterfaceTypedNil }}OK{{ else }}{{ end }} {{ if .NonEmptyInterfaceTypedNil }}{{ else }}OK{{ end }} The functions `not`, `or`, and `and` all use the same `truth` function, which unwraps any concrete interface value before passing it to `isTrue`. `if` and `with` also use `isTrue` to establish truth, but was missing the interface indirect call. Fixes golang#30501
I would appreciate if this was considered for
In Go <= I maintain a Go project that I'm pretty sure has the most widespread use of end user defined Go templates, and I don't think I can wait for 3-4 months for a Go main release before I address this issue for that user base, which I fear would mean a temporary fork of some sort ... |
If you think there was a regression in 1.12, could you share a program that does something sensible on 1.11.5 and something different on 1.12? |
As I said, this is not a regression in 1.12. It behaves like this at least >= Go 1.10 <= Go 1.12. |
This definitely should not be backported to 1.12. It is quite likely that some existing programs depend on the current behavior, even if it is buggy. Programs that depend on relatively benign bugs should only break at major releases. (see also http://www.hyrumslaw.com/) |
I was actually going to say that this would be a somewhat risky change to do in 1.13, as there's a notable chance that some templates out there will break with the change. That's still something we can consider for 1.13 with a proper changelog entry, but not for 1.12.x. If a template worked in 1.11.x and 1.12, it shouldn't break in 1.12.1; even if one could argue that the template was incorrect. |
OK, then I need to take on the work myself and fix this for all the users of my applications. But you really, really need to add a big warning sign somewhere visible in the documentation. If you don't think that's a good idea, think what you would do if this somehow failed in certain common situations: if true != !false {
log.Fatal("black hole?")
}
@bcmills you and I have somewhat different views on bugs and their severity, but I had to look in the dictionary for the word |
I personally think having this bug filed and fixed for 1.13, whichever the fix is, would be enough. Sure there's a known bug in 1.12.x, but we don't add documentation warnings for those.
I think Bryan said "benign" in the context that this is a bug which simply makes a template's behavior slightly different and/or inconsistent. In contrast, a "bad" bug would make a program crash, error, or would be a regression from 1.11 to 1.12. |
@mvdan OK, I don't agree. |
This issue is a rework of #30481, which I felt was closed a little prematurely. This is, on one or more levels, a real issue that needs to be addressed. I will try to make this shorter and to the point.
The program below prints:
Also see https://play.golang.org/p/HzwnX062jjk
The documentation for template.IsTrue states that
So, while I understand that
Nil != nil
in the second example above, which, I suspect, is part of the reason why thetemplate
package usesreflect
. I would expect that all values that is truthful according totemplate.IsTrue
is also truthful inif
andwith
.The text was updated successfully, but these errors were encountered: