Fix Python module names. (#4473)

In particular, ensure that they are keyword-safe. This affects
`aws:lambda:*` in particular: prior to these changes, we were generating
code into `pulumi_aws.lamdba`, which is not referencable due to its use
of the `lamdba` keyword. With these changes, we generate code into
`pulumi_aws.lambda_`.

There is also a small fix for multi-line non-formatted strings: these
strings do not need escaped braces.
This commit is contained in:
Pat Gavlin 2020-04-24 08:52:36 -07:00 committed by GitHub
parent 739634c702
commit af344d9b72
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 9 deletions

View file

@ -16,6 +16,9 @@ CHANGELOG
- Ensure Go accessor methods correctly support nested fields of optional outputs
[#4456](https://github.com/pulumi/pulumi/pull/4456)
- Ensure generated Python module names are keyword-safe.
[#4473](https://github.com/pulumi/pulumi/pull/4473)
## 2.0.0 (2020-04-16)

View file

@ -1152,7 +1152,7 @@ func GeneratePackage(tool string, pkg *schema.Package, extraFiles map[string][]b
var getMod func(token string) *modContext
getMod = func(token string) *modContext {
modName := pkg.TokenToModule(token)
modName := PyName(pkg.TokenToModule(token))
mod, ok := modules[modName]
if !ok {
mod = &modContext{

View file

@ -72,7 +72,7 @@ func pyName(pulumiName string, isObjectKey bool) string {
if isObjectKey {
return fmt.Sprintf("%q", pulumiName)
}
return PyName(cleanName(pulumiName))
return PyName(pulumiName)
}
// genLeadingTrivia generates the list of leading trivia assicated with a given token.
@ -167,7 +167,13 @@ func (g *generator) genNode(w io.Writer, n hcl2.Node) {
func resourceTypeName(r *hcl2.Resource) (string, string, string, hcl.Diagnostics) {
// Compute the resource type from the Pulumi type token.
pkg, module, member, diagnostics := r.DecomposeToken()
return pyName(pkg, false), strings.Replace(module, "/", ".", -1), title(member), diagnostics
components := strings.Split(module, ".")
for i, component := range components {
components[i] = PyName(component)
}
return pyName(pkg, false), strings.Join(components, "."), title(member), diagnostics
}
// makeResourceName returns the expression that should be emitted for a resource's "name" parameter given its base name

View file

@ -172,9 +172,15 @@ func functionName(tokenArg model.Expression) (string, string, string, hcl.Diagno
token := tokenArg.(*model.TemplateExpression).Parts[0].(*model.LiteralValueExpression).Value.AsString()
tokenRange := tokenArg.SyntaxNode().Range()
// Compute the resource type from the Pulumi type token.
// Compute the function name from the Pulumi type token.
pkg, module, member, diagnostics := hcl2.DecomposeToken(token, tokenRange)
return cleanName(pkg), strings.Replace(module, "/", ".", -1), title(member), diagnostics
components := strings.Split(module, ".")
for i, component := range components {
components[i] = PyName(component)
}
return cleanName(pkg), strings.Join(components, "."), title(member), diagnostics
}
var functionImports = map[string]string{
@ -439,7 +445,7 @@ func (g *generator) GenTemplateExpression(w io.Writer, expr *model.TemplateExpre
}
}
prefix, isMultiLine, quotes := "", false, `"`
formatted, isMultiLine, quotes := false, false, `"`
for i, part := range expr.Parts {
if lit, ok := part.(*model.LiteralValueExpression); ok {
if !isMultiLine && lit.Type() == model.StringType {
@ -455,17 +461,21 @@ func (g *generator) GenTemplateExpression(w io.Writer, expr *model.TemplateExpre
isMultiLine, quotes = true, `"""`
}
} else {
prefix = "f"
formatted = true
}
}
b := bufio.NewWriter(w)
defer b.Flush()
prefix := ""
if formatted {
prefix = "f"
}
g.Fprintf(b, "%s%s", prefix, quotes)
for _, expr := range expr.Parts {
if lit, ok := expr.(*model.LiteralValueExpression); ok && lit.Type() == model.StringType {
g.genEscapedString(b, lit.Value.AsString(), !isMultiLine, true)
g.genEscapedString(b, lit.Value.AsString(), !isMultiLine, formatted)
} else {
g.Fgenf(b, "{%.v}", expr)
}

View file

@ -72,7 +72,7 @@ func PyName(name string) string {
var components []string // The components that will be joined together with underscores
var currentComponent []rune // The characters composing the current component being built
state := stateFirst
for _, char := range name {
for _, char := range cleanName(name) {
switch state {
case stateFirst:
if unicode.IsUpper(char) {