Skip to content

Commit

Permalink
Add protobuf python keyword support in path for stub generator. Also …
Browse files Browse the repository at this point in the history
…added tests for

keywords in path

PiperOrigin-RevId: 549715333
  • Loading branch information
anandolee authored and copybara-github committed Jul 20, 2023
1 parent 61c6b6a commit 4cc258a
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 23 deletions.
6 changes: 5 additions & 1 deletion src/google/protobuf/compiler/python/generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ void Generator::PrintTopBoilerplate() const {

// Prints Python imports for all modules imported by |file|.
void Generator::PrintImports() const {
bool has_importlib = false;
for (int i = 0; i < file_->dependency_count(); ++i) {
absl::string_view filename = file_->dependency(i)->name();

Expand All @@ -396,7 +397,10 @@ void Generator::PrintImports() const {
// module name and import it using importlib. Otherwise the usual kind of
// import statement would result in a syntax error from the presence of
// the keyword.
printer_->Print("import importlib\n");
if (has_importlib == false) {
printer_->Print("import importlib\n");
has_importlib = true;
}
printer_->Print("$alias$ = importlib.import_module('$name$')\n", "alias",
module_alias, "name", module_name);
} else {
Expand Down
47 changes: 28 additions & 19 deletions src/google/protobuf/compiler/python/pyi_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,41 +151,50 @@ void CheckImportModules(const Descriptor* descriptor,
}

void PyiGenerator::PrintImportForDescriptor(
const FileDescriptor& desc,
absl::flat_hash_set<std::string>* seen_aliases) const {
const FileDescriptor& desc, absl::flat_hash_set<std::string>* seen_aliases,
bool* has_importlib) const {
const std::string& filename = desc.name();
std::string module_name_owned = StrippedModuleName(filename);
absl::string_view module_name(module_name_owned);
size_t last_dot_pos = module_name.rfind('.');
std::string import_statement;
if (last_dot_pos == std::string::npos) {
import_statement = absl::StrCat("import ", module_name);
} else {
import_statement =
absl::StrCat("from ", module_name.substr(0, last_dot_pos), " import ",
module_name.substr(last_dot_pos + 1));
module_name = module_name.substr(last_dot_pos + 1);
}
std::string alias = absl::StrCat("_", module_name);
std::string alias = absl::StrCat("_", module_name.substr(last_dot_pos + 1));
// Generate a unique alias by adding _1 suffixes until we get an unused alias.
while (seen_aliases->find(alias) != seen_aliases->end()) {
absl::StrAppend(&alias, "_1");
}
printer_->Print("$statement$ as $alias$\n", "statement",
import_statement, "alias", alias);
import_map_[filename] = alias;
seen_aliases->insert(alias);
if (ContainsPythonKeyword(module_name)) {
if (*has_importlib == false) {
printer_->Print("import importlib\n");
*has_importlib = true;
}
printer_->Print("$alias$ = importlib.import_module('$name$')\n", "alias",
alias, "name", module_name);
} else {
std::string import_statement;
if (last_dot_pos == std::string::npos) {
import_statement = absl::StrCat("import ", module_name);
} else {
import_statement =
absl::StrCat("from ", module_name.substr(0, last_dot_pos), " import ",
module_name.substr(last_dot_pos + 1));
}
printer_->Print("$statement$ as $alias$\n", "statement", import_statement,
"alias", alias);
import_map_[filename] = alias;
seen_aliases->insert(alias);
}
}

void PyiGenerator::PrintImports() const {
// Prints imported dependent _pb2 files.
absl::flat_hash_set<std::string> seen_aliases;
bool has_importlib = false;
for (int i = 0; i < file_->dependency_count(); ++i) {
const FileDescriptor* dep = file_->dependency(i);
PrintImportForDescriptor(*dep, &seen_aliases);
PrintImportForDescriptor(*dep, &seen_aliases, &has_importlib);
for (int j = 0; j < dep->public_dependency_count(); ++j) {
PrintImportForDescriptor(
*dep->public_dependency(j), &seen_aliases);
PrintImportForDescriptor(*dep->public_dependency(j), &seen_aliases,
&has_importlib);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/google/protobuf/compiler/python/pyi_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenera
std::string* error) const override;

private:
void PrintImportForDescriptor(
const FileDescriptor& desc,
absl::flat_hash_set<std::string>* seen_aliases) const;
void PrintImportForDescriptor(const FileDescriptor& desc,
absl::flat_hash_set<std::string>* seen_aliases,
bool* has_importlib) const;
template <typename DescriptorT>
void Annotate(const std::string& label, const DescriptorT* descriptor) const;
void PrintImports() const;
Expand Down

0 comments on commit 4cc258a

Please sign in to comment.