Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ class PythonCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)
out.puts
out.puts(s"class ${type2class(enumName)}(IntEnum):")
out.inc
enumColl.foreach { case (id: Long, label: String) => out.puts(s"$label = ${translator.doIntLiteral(id)}") }
enumColl.foreach { case (id: Long, label: String) => out.puts(s"${escapePythonKeyword(label)} = ${translator.doIntLiteral(id)}") }
out.dec
}

Expand All @@ -498,7 +498,7 @@ class PythonCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig)

override def publicMemberName(id: Identifier): String =
id match {
case InstanceIdentifier(name) => name
case InstanceIdentifier(name) => escapePythonKeyword(name)
case _ => idToStr(id)
}

Expand Down Expand Up @@ -546,10 +546,12 @@ object PythonCompiler extends LanguageCompilerStatic
config: RuntimeConfig
): LanguageCompiler = new PythonCompiler(tp, config)

override def type2class(name: String): String = escapePythonKeyword(super.type2class(name))

def idToStr(id: Identifier): String =
id match {
case SpecialIdentifier(name) => name
case NamedIdentifier(name) => name
case SpecialIdentifier(name) => escapePythonKeyword(name)
case NamedIdentifier(name) => escapePythonKeyword(name)
case NumberedIdentifier(idx) => s"_${NumberedIdentifier.TEMPLATE}$idx"
case InstanceIdentifier(name) => s"_m_$name"
case RawIdentifier(innerId) => s"_raw_${idToStr(innerId)}"
Expand Down Expand Up @@ -584,4 +586,51 @@ object PythonCompiler extends LanguageCompilerStatic
}
)
}

// Python reserved keywords that need to be escaped
// https://docs.python.org/3/reference/lexical_analysis.html#keywords
private val KEYWORDS = Set(
"and",
"as",
"assert",
"async",
"await",
"break",
"class",
"continue",
"def",
"del",
"elif",
"else",
"except",
"False",
"finally",
"for",
"from",
"global",
"if",
"import",
"in",
"is",
"lambda",
"None",
"nonlocal",
"not",
"or",
"pass",
"raise",
"return",
"True",
"try",
"while",
"with",
"yield",
)

def escapePythonKeyword(name: String): String =
if (KEYWORDS.contains(name)) {
s"${name}_"
} else {
name
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class PythonTranslator(provider: TypeProvider, importList: ImportList, config: R
}
}
override def doName(s: String) =
s
PythonCompiler.escapePythonKeyword(s)
override def doInternalName(id: Identifier): String =
PythonCompiler.privateMemberName(id)

Expand All @@ -109,7 +109,7 @@ class PythonTranslator(provider: TypeProvider, importList: ImportList, config: R
if (isExternal) {
PythonCompiler.externalTypeDeclaration(ExternalEnum(enumSpec), importList, config)
}
s"${PythonCompiler.types2class(enumSpec.name, isExternal)}.$label"
s"${PythonCompiler.types2class(enumSpec.name, isExternal)}.${doName(label)}"
}
override def doEnumById(enumSpec: EnumSpec, id: String): String =
s"${PythonCompiler.kstreamName}.resolve_enum(${PythonCompiler.types2class(enumSpec.name, enumSpec.isExternal(provider.nowClass))}, $id)"
Expand Down
Loading