diff --git a/cpp/src/slice2py/PythonUtil.cpp b/cpp/src/slice2py/PythonUtil.cpp index 44ddd8ecbb5..da34feed6d3 100644 --- a/cpp/src/slice2py/PythonUtil.cpp +++ b/cpp/src/slice2py/PythonUtil.cpp @@ -230,6 +230,21 @@ lookupKwd(const string& name) return found ? "_" + name : name; } +static string +getDictLookup(const ContainedPtr& cont, const string& suffix = "", const string& prefix = "") +{ + string scope = Slice::Python::scopedToName(cont->scope()); + assert(!scope.empty()); + + string package = Slice::Python::getPackageMetadata(cont); + if (!package.empty()) + { + scope = package + "." + scope; + } + + return "'" + suffix + Slice::Python::fixIdent(cont->name() + prefix) + "' not in _M_" + scope + "__dict__"; +} + // // ModuleVisitor implementation. // @@ -362,8 +377,11 @@ Slice::Python::CodeVisitor::visitClassDecl(const ClassDeclPtr& p) string scoped = p->scoped(); if (_classHistory.count(scoped) == 0) { + _out << sp << nl << "if " << getDictLookup(p) << ':'; + _out.inc(); _out << nl << "_M_" << getAbsolute(p, "_t_") << " = IcePy.declareValue('" << scoped << "')"; _classHistory.insert(scoped); // Avoid redundant declarations. + _out.dec(); } } @@ -376,9 +394,12 @@ Slice::Python::CodeVisitor::visitInterfaceDecl(const InterfaceDeclPtr& p) string scoped = p->scoped(); if (_classHistory.count(scoped) == 0) { + _out << sp << nl << "if " << getDictLookup(p) << ':'; + _out.inc(); _out << nl << "_M_" << getAbsolute(p, "_t_", "Disp") << " = IcePy.declareClass('" << scoped << "')"; _out << nl << "_M_" << getAbsolute(p, "_t_", "Prx") << " = IcePy.declareProxy('" << scoped << "')"; _classHistory.insert(scoped); // Avoid redundant declarations. + _out.dec(); } } @@ -450,6 +471,9 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) string valueName = fixIdent(p->name()); ClassDefPtr base = p->base(); + _out << sp << nl << "if " << getDictLookup(p) << ':'; + _out.inc(); + _out << nl << "_M_" << abs << " = None"; _out << nl << "class " << valueName << '('; if (!base) @@ -602,6 +626,7 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) { _classHistory.insert(scoped); // Avoid redundant declarations. } + _out.dec(); return false; } @@ -620,6 +645,9 @@ Slice::Python::CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) string prxType = getAbsolute(p, "_t_", "Prx"); InterfaceList bases = p->bases(); + _out << sp << nl << "if " << getDictLookup(p) << ':'; + _out.inc(); + // TODO: remove this interface-by-value. _out << sp << nl << "_M_" << type << " = IcePy.defineValue('" << scoped << "', Ice.Value, -1, "; writeMetaData(p->getMetaData()); @@ -1002,6 +1030,7 @@ Slice::Python::CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) { _classHistory.insert(scoped); // Avoid redundant declarations. } + _out.dec(); return false; } @@ -1013,6 +1042,9 @@ Slice::Python::CodeVisitor::visitExceptionStart(const ExceptionPtr& p) string abs = getAbsolute(p); string name = fixIdent(p->name()); + _out << sp << nl << "if " << getDictLookup(p) << ':'; + _out.inc(); + _out << nl << "_M_" << abs << " = None"; _out << nl << "class " << name << '('; ExceptionPtr base = p->base(); @@ -1141,6 +1173,8 @@ Slice::Python::CodeVisitor::visitExceptionStart(const ExceptionPtr& p) registerName(name); + _out.dec(); + return false; } @@ -1163,6 +1197,9 @@ Slice::Python::CodeVisitor::visitStructStart(const StructPtr& p) } } + _out << sp << nl << "if " << getDictLookup(p) << ':'; + _out.inc(); + _out << nl << "_M_" << abs << " = None"; _out << nl << "class " << name << "(object):"; _out.inc(); @@ -1410,25 +1447,36 @@ Slice::Python::CodeVisitor::visitStructStart(const StructPtr& p) registerName(name); + _out.dec(); + return false; } void Slice::Python::CodeVisitor::visitSequence(const SequencePtr& p) { + _out << sp << nl << "if " << getDictLookup(p) << ':'; + _out.inc(); + // Emit the type information. StringList metaData = p->getMetaData(); string scoped = p->scoped(); + _out << nl << "_M_" << getAbsolute(p, "_t_") << " = IcePy.defineSequence('" << scoped << "', "; writeMetaData(metaData); _out << ", "; writeType(p->type()); _out << ")"; + + _out.dec(); } void Slice::Python::CodeVisitor::visitDictionary(const DictionaryPtr& p) { + _out << sp << nl << "if " << getDictLookup(p) << ':'; + _out.inc(); + // Emit the type information. string scoped = p->scoped(); _out << nl << "_M_" << getAbsolute(p, "_t_") << " = IcePy.defineDictionary('" << scoped << "', "; @@ -1438,11 +1486,16 @@ Slice::Python::CodeVisitor::visitDictionary(const DictionaryPtr& p) _out << ", "; writeType(p->valueType()); _out << ")"; + + _out.dec(); } void Slice::Python::CodeVisitor::visitEnum(const EnumPtr& p) { + _out << sp << nl << "if " << getDictLookup(p) << ':'; + _out.inc(); + string scoped = p->scoped(); string abs = getAbsolute(p); string name = fixIdent(p->name()); @@ -1499,16 +1552,23 @@ Slice::Python::CodeVisitor::visitEnum(const EnumPtr& p) _out << ", " << name << "._enumerators)"; registerName(name); + + _out.dec(); } void Slice::Python::CodeVisitor::visitConst(const ConstPtr& p) { + _out << sp << nl << "if " << getDictLookup(p) << ':'; + _out.inc(); + Slice::TypePtr type = p->type(); string name = fixIdent(p->name()); _out << sp << nl << "_M_" << getAbsolute(p) << " = "; writeConstantValue(type, p->valueType(), p->value()); + + _out.dec(); } string