-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Accept UnaryMinusExpression as class parameter type #9269
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
Conversation
83ed38b
to
c3054b4
Compare
@@ -36,6 +36,8 @@ def severity_producer | |||
p[Issues::NAME_WITH_HYPHEN] = :error | |||
p[Issues::EMPTY_RESOURCE_SPECIALIZATION] = :ignore | |||
p[Issues::CLASS_NOT_VIRTUALIZABLE] = :error | |||
|
|||
p[Issues::ILLEGAL_NONLITERAL_PARAMETER_TYPE] = Puppet[:strict] == :off ? :ignore : Puppet[:strict] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since strict
defaults to warning
in 7.x, this would effectively cause incorrect types to no longer fail compilation for the cases we fixed in adbb02c, like Integer[1-3]
.
We could instead do the following for both main and 7.x branches
Puppet[:strict] == :off ? :ignore : :error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the least surprising thing would be to let it default to warning
. In the case there is just a warning would the type just not be enforced? That doesn't seem terribly dangerous?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit subtle. In the case of Integer[1-3]
, the type is actually valid, because it evaluates to Integer[-2]
, which in the context of a class parameter Integer[-2] $i
means it will accept integers >= -2. However, the manifest author intended to specify the range Integer[1, 3]
. So if you pass a value bigger than 3, then it passes validation (surprise)!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good. Double checked ranges work as expected locally
diff --git a/spec/unit/pops/evaluator/literal_evaluator_spec.rb b/spec/unit/pops/evaluator/literal_evaluator_spec.rb
index 63ee699a78..90a0aeb201 100644
--- a/spec/unit/pops/evaluator/literal_evaluator_spec.rb
+++ b/spec/unit/pops/evaluator/literal_evaluator_spec.rb
@@ -18,6 +18,8 @@ describe "Puppet::Pops::Evaluator::LiteralEvaluator" do
'a::b' => 'a::b',
'Integer[1]' => [1],
'Integer[-1]' => [-1],
+ 'Integer[-5, -1]' => [-5, -1],
+ 'Integer[-5, 5]' => [-5, 5],
'File' => "file",
I like that it will follow strict
settings. So effectively it will default to warning
in 7 and error
in 8. 👍
7138802
to
7f438d2
Compare
Previously, class parameters of the form `Integer[-1] $param` would fail compilation, because the value `-1` was lexed as a UnaryMinusExpression containing a LiteralInteger. And since the LiteralEvaluator didn't implement the `literal_UnaryMinusExpression` method, the visitor called `literal_XXX` for each ancestor class, until reaching `literal_Object`, which always raises. This adds the `literal_UnaryMinusExpression` method and returns -1 times the expression it wraps. This is similar to how the TypeParser interprets UnaryMinusExpressions[1]. [1] https://github.com/puppetlabs/puppet/blob/8.5.0/lib/puppet/pops/types/type_parser.rb#L161
If strict is off, the issue will be ignored. If strict is warning, then a warning will be reported, but compilation will continue: Warning: The parameter '$i' must be a literal type, not a Puppet::Pops::Model::AccessExpression If strict is error, then compilation will fail.
a3380ab
to
7eeb236
Compare
The "undef to nil" test is special because otherwise the value nil when interpolated in the name of the test results in empty string.
7eeb236
to
17ba937
Compare
Successfully created backport PR for |
I am getting this error on fresh install foreman running on alma 8 foreman-installer [root@localhost ~]# vi /usr/share/foreman-installer/modules/redis/manifests/init.pp
|
Has the changed already pushed to the repo as it seems that we still pulling wrong code |
@rembun We released Puppet 7.29.1 and 8.5.1 today with this fix included. Please let us know if those versions do not resolve this issue for you. |
This fix is not sufficient (I tested using 7.29.1. gem), it breaks arithmetic in general. Examples from my code: Integer[0, 3*3600] $random_delay = 1800,
Integer[0, 24*60] $downtime_duration = 10, edit: 8.5.1 gem has same failure:
|
@donoghuc isn't that an unusual thing to do in a minor release? |
@kjetilho please file a new GH issue instead of reusing this one. In the new issue, can you explain what you mean by "it breaks arithmetic in general"? How exactly is it broken? What behavior do you see? |
@joshcooper - I included both my code and the error message. What more do you need? @donoghuc - thanks, I see it was intended to break my code. In which case I must agree with @ekohl, that seems like an unusual thing to do in a minor release, and at least warrants an entry in the release notes. In any case, the goal of "provid[ing] a descriptive warning if parameter(s) are not literal" was not met IMHO. It is not descriptive for users (no users have any idea what an |
@kjetilho you said, "This fix is not sufficient (I tested using 7.29.1. gem), it breaks arithmetic in general" And you gave the resulting message, "The parameter '$random_delay' must be a literal type, not a Puppet::Pops::Model::AccessExpression" However, isn't it true that in 7.29.1 the message is printed as a warning in the puppetserver logs? If so, that's very different than "it breaks". If not, are you running with |
Ah, I am sorry - my pipeline failed on the first step, which was |
@kjetilho ah makes sense, thank you! When I would expect puppet to be able to add warnings to the language runtime and evaluation without breaking all module CI, as described in https://github.com/puppetlabs/puppet/blob/7.29.1/lib/puppet/defaults.rb#L192-L204. It seems puppet-syntax doesn't distinguish between warnings and errors in manifests https://github.com/voxpupuli/puppet-syntax/blob/8114392547895ef352cfa66c3becdc3cf33859fb/lib/puppet-syntax/manifests.rb#L24-L25 but it does for templates https://github.com/voxpupuli/puppet-syntax/blob/8114392547895ef352cfa66c3becdc3cf33859fb/lib/puppet-syntax/templates.rb#L38-L57 Maybe it should for manifests so it's clear the "must be a literal type" message is a warning and not an error? Thoughts @bastelfreak |
Yes, the syntax check is strict, but I think it is good to fix even deprecations early. The puppet-lint in my CI pipeline, is strict, too. It even regards trailing whitespace a fatal error :) To summarise my position: I'm fine with the change in behaviour - but I would love to see the warning message improved to something more easily human understandable if possible.
This indicates to me that the problem is with my parameter value, not the parameter declaration. How about:
Of course my intuition is not everyone else's intution, so that's just my 2 cents. |
I agree. I think the message isn't very user friendly at the moment.
Yes, that's the default behaviour And as stated on slack: I think this is a breaking change and should have been landed in Puppet 9 and not in a minor release. And thinking further about it I argue that puppet 7 and puppet 8 should print a deprecation message, not a warning. and on Puppet 8 it should be an error or warning. And the puppet-syntax behaviour for deprecations is configurable. |
This is a bug, we should be using the
In the past, we have introduced new language validations in minor or patch releases in one of two ways: First, the issue is introduced as a deprecation. It is not under control of
Second, the issue is introduced under control of
The reason we went with the "under control of strict" route is because class parameters were always assumed to be literal and puppet's But given the precedent with how we handled validations in 5.x and feedback on this thread, I agree we should switch the |
sounds good to me! |
Previously, class parameters of the form
Integer[-1] $param
would failcompilation, because the value
-1
was lexed as a UnaryMinusExpressioncontaining a LiteralInteger. And since the LiteralEvaluator didn't implement the
literal_UnaryMinusExpression
method, the visitor calledliteral_XXX
for eachancestor class, until reaching
literal_Object
, which always raises.This adds the
literal_UnaryMinusExpression
method and returns -1 timesthe expression it wraps. This is similar to how the TypeParser interprets
UnaryMinusExpressions[1].
If strict is off, the issue will be ignored. If strict is warning, then a
warning will be reported, but compilation will continue:
If strict is error, then compilation will fail.
Fixes #9268
[1] https://github.com/puppetlabs/puppet/blob/8.5.0/lib/puppet/pops/types/type_parser.rb#L161