From 843a1cc0b4dff3cefd4ee2f431ab3f74d418fbda Mon Sep 17 00:00:00 2001
From: Victor Zverovich <viz@meta.com>
Date: Sat, 19 Oct 2024 07:25:00 -0700
Subject: [PATCH] Cleanup python generators

Summary: The current organization of Python generator "utils" doesn't make much sense because `py3/util.h` is used not just from py3 but from multiple python generators. Merge it with `python/util.h` to reflect that, fix naming conventions and remove an unnecessary dependency.

Reviewed By: yoney

Differential Revision: D64548608

fbshipit-source-id: 1d76865e0735cc47ef54587d8f151a8bff5cca42
---
 thrift/compiler/CMakeLists.txt                |   1 -
 thrift/compiler/generate/py3/util.cpp         | 131 ------------------
 thrift/compiler/generate/py3/util.h           | 116 ----------------
 thrift/compiler/generate/python/util.cc       | 111 +++++++++++++++
 thrift/compiler/generate/python/util.h        |  91 ++++++++++++
 .../generate/t_mstch_py3_generator.cc         |  42 +++---
 .../generate/t_mstch_pyi_generator.cc         |   2 +-
 .../generate/t_mstch_python_capi_generator.cc |   5 +-
 .../generate/t_mstch_python_generator.cc      |  11 +-
 thrift/compiler/generate/t_py_generator.cc    |   2 +-
 thrift/compiler/test/generate_common_test.cc  |   2 +-
 .../{py3_util_test.cc => python_util_test.cc} |  12 +-
 12 files changed, 240 insertions(+), 286 deletions(-)
 delete mode 100644 thrift/compiler/generate/py3/util.cpp
 delete mode 100644 thrift/compiler/generate/py3/util.h
 rename thrift/compiler/test/{py3_util_test.cc => python_util_test.cc} (73%)

diff --git a/thrift/compiler/CMakeLists.txt b/thrift/compiler/CMakeLists.txt
index cd10384e9dc..8e995cd35c9 100644
--- a/thrift/compiler/CMakeLists.txt
+++ b/thrift/compiler/CMakeLists.txt
@@ -134,7 +134,6 @@ add_library(
   generate/cpp/util.cc
   generate/go/util.cc
   generate/java/util.cc
-  generate/py3/util.cpp
   generate/python/util.cc
   generate/rust/util.cc
 )
diff --git a/thrift/compiler/generate/py3/util.cpp b/thrift/compiler/generate/py3/util.cpp
deleted file mode 100644
index cb1469728c4..00000000000
--- a/thrift/compiler/generate/py3/util.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <regex>
-
-#include <boost/algorithm/string/replace.hpp>
-#include <thrift/compiler/generate/py3/util.h>
-
-namespace apache::thrift::compiler {
-
-std::vector<std::string> get_py3_namespace(const t_program* prog) {
-  t_program::namespace_config conf;
-  conf.no_top_level_domain = true;
-  conf.no_filename = true;
-  return prog->gen_namespace_or_default("py3", conf);
-}
-
-std::string get_py3_namespace_with_name_and_prefix(
-    const t_program* prog, const std::string& prefix, const std::string& sep) {
-  std::ostringstream ss;
-  if (!prefix.empty()) {
-    ss << prefix << sep;
-  }
-  for (const auto& name : get_py3_namespace(prog)) {
-    ss << name << sep;
-  }
-  ss << prog->name();
-  return ss.str();
-}
-
-void strip_cpp_comments_and_newlines(std::string& s) {
-  // strip c-style comments
-  auto fr = s.find("/*");
-  while (fr != std::string::npos) {
-    auto to = s.find("*/", fr + 2);
-    if (to == std::string::npos) {
-      throw std::runtime_error{"no matching */ for annotation comments"};
-    }
-    s.erase(fr, to - fr + 2);
-    fr = s.find("/*", fr);
-  }
-  // strip cpp-style comments
-  s.replace(
-      s.begin(),
-      s.end(),
-      std::regex_replace(
-          s,
-          std::regex("//.*(?=$|\\n)"), /* simulate multiline regex */
-          ""));
-
-  // strip newlines
-  boost::algorithm::replace_all(s, "\n", " ");
-}
-
-namespace py3 {
-CachedProperties::CachedProperties(
-    std::string _template, std::string type, std::string flatName)
-    : cppTemplate_(std::move(_template)),
-      cppType_(std::move(type)),
-      flatName_(std::move(flatName)) {
-  strip_cpp_comments_and_newlines(cppType_);
-}
-
-std::string CachedProperties::to_cython_template() const {
-  // handle special built-ins first:
-  if (cppTemplate_ == "std::vector") {
-    return "vector";
-  } else if (cppTemplate_ == "std::set") {
-    return "cset";
-  } else if (cppTemplate_ == "std::map") {
-    return "cmap";
-  }
-  // then default handling:
-  return boost::algorithm::replace_all_copy(cppTemplate_, "::", "_");
-}
-
-std::string CachedProperties::to_cython_type() const {
-  if (cppType_ == "") {
-    return "";
-  }
-  std::string cython_type = cppType_;
-  boost::algorithm::replace_all(cython_type, "::", "_");
-  boost::algorithm::replace_all(cython_type, "<", "_");
-  boost::algorithm::replace_all(cython_type, ">", "");
-  boost::algorithm::replace_all(cython_type, " ", "");
-  boost::algorithm::replace_all(cython_type, ", ", "_");
-  boost::algorithm::replace_all(cython_type, ",", "_");
-  return cython_type;
-}
-
-bool CachedProperties::is_default_template(
-    const apache::thrift::compiler::t_type* type) const {
-  return (!type->is_container() && cppTemplate_ == "") ||
-      (type->is_list() && cppTemplate_ == "std::vector") ||
-      (type->is_set() && cppTemplate_ == "std::set") ||
-      (type->is_map() && cppTemplate_ == "std::map");
-}
-
-void CachedProperties::set_flat_name(
-    const apache::thrift::compiler::t_program* thisProg,
-    const apache::thrift::compiler::t_type* type,
-    const std::string& extra) {
-  std::string custom_prefix;
-  if (!is_default_template(type)) {
-    custom_prefix = to_cython_template() + "__";
-  } else if (cppType_ != "") {
-    custom_prefix = to_cython_type() + "__";
-  }
-  const t_program* typeProgram = type->program();
-  if (typeProgram && typeProgram != thisProg) {
-    custom_prefix += typeProgram->name() + "_";
-  }
-  custom_prefix += extra;
-  flatName_ = std::move(custom_prefix);
-}
-
-} // namespace py3
-} // namespace apache::thrift::compiler
diff --git a/thrift/compiler/generate/py3/util.h b/thrift/compiler/generate/py3/util.h
deleted file mode 100644
index e3c508e1766..00000000000
--- a/thrift/compiler/generate/py3/util.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <map>
-#include <string>
-#include <unordered_set>
-
-#include <thrift/compiler/ast/t_program.h>
-#include <thrift/compiler/lib/uri.h>
-
-namespace apache::thrift::compiler {
-
-std::vector<std::string> get_py3_namespace(const t_program* prog);
-
-std::string get_py3_namespace_with_name_and_prefix(
-    const t_program* prog,
-    const std::string& prefix,
-    const std::string& sep = ".");
-
-inline const std::unordered_set<std::string>& get_python_reserved_names() {
-  static const std::unordered_set<std::string> keywords = {
-      "False",  "None",    "True",    "and",      "as",       "assert", "async",
-      "await",  "break",   "class",   "continue", "def",      "del",    "elif",
-      "else",   "except",  "finally", "for",      "from",     "global", "if",
-      "import", "in",      "is",      "lambda",   "nonlocal", "not",    "or",
-      "pass",   "raise",   "return",  "try",      "while",    "with",   "yield",
-      "cdef",   "cimport", "cpdef",   "cppclass", "ctypedef",
-  };
-  return keywords;
-}
-
-/**
- * strip comments and newlines off cpp annotation text
- */
-void strip_cpp_comments_and_newlines(std::string& s);
-
-namespace py3 {
-
-class CachedProperties {
- public:
-  CachedProperties(
-      std::string _template, std::string type, std::string flatName);
-
-  const std::string& cppTemplate() const { return cppTemplate_; }
-  const std::string& cppType() const { return cppType_; }
-  const std::string& flatName() const { return flatName_; }
-
-  std::string to_cython_template() const;
-
-  std::string to_cython_type() const;
-
-  bool is_default_template(const apache::thrift::compiler::t_type* type) const;
-
-  void set_flat_name(
-      const apache::thrift::compiler::t_program* thisProg,
-      const apache::thrift::compiler::t_type* type,
-      const std::string& extra);
-
- private:
-  const std::string cppTemplate_;
-  std::string cppType_;
-  std::string flatName_;
-};
-
-template <class T>
-std::string get_py3_name(const T& node) {
-  // Reserved Cython / Python keywords that are not blocked by thrift grammer
-  // TODO: get rid of this list and force users to rename explicitly
-  static const std::unordered_set<std::string> cython_keywords = {
-      "DEF",
-      "ELIF",
-      "ELSE",
-      "IF",
-      "cdef",
-      "cimport",
-      "cpdef",
-      "cppclass",
-      "ctypedef",
-  };
-
-  if (const t_const* annot =
-          node.find_structured_annotation_or_null(kPythonNameUri)) {
-    if (auto name =
-            annot->get_value_from_structured_annotation_or_null("name")) {
-      return name->get_string();
-    }
-  }
-  if (const auto* name = node.find_annotation_or_null("py3.name")) {
-    return *name;
-  }
-  const auto& name = node.get_name();
-  const auto& python_keywords = get_python_reserved_names();
-  if (cython_keywords.find(name) != cython_keywords.end() ||
-      python_keywords.find(name) != python_keywords.end()) {
-    return name + "_";
-  }
-  return name;
-}
-
-} // namespace py3
-} // namespace apache::thrift::compiler
diff --git a/thrift/compiler/generate/python/util.cc b/thrift/compiler/generate/python/util.cc
index 0f2fd3a6978..f1638b89a07 100644
--- a/thrift/compiler/generate/python/util.cc
+++ b/thrift/compiler/generate/python/util.cc
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+#include <thrift/compiler/generate/python/util.h>
+
+#include <regex>
+#include <boost/algorithm/string/replace.hpp>
 #include <thrift/compiler/generate/cpp/util.h>
 
 namespace apache::thrift::compiler {
@@ -26,4 +30,111 @@ bool is_type_iobuf(const t_type* type) {
   return is_type_iobuf(cpp2::get_type(type));
 }
 
+std::vector<std::string> get_py3_namespace(const t_program* prog) {
+  t_program::namespace_config conf;
+  conf.no_top_level_domain = true;
+  conf.no_filename = true;
+  return prog->gen_namespace_or_default("py3", conf);
+}
+
+std::string get_py3_namespace_with_name_and_prefix(
+    const t_program* prog, const std::string& prefix, const std::string& sep) {
+  std::ostringstream ss;
+  if (!prefix.empty()) {
+    ss << prefix << sep;
+  }
+  for (const auto& name : get_py3_namespace(prog)) {
+    ss << name << sep;
+  }
+  ss << prog->name();
+  return ss.str();
+}
+
+void strip_cpp_comments_and_newlines(std::string& s) {
+  // strip c-style comments
+  auto fr = s.find("/*");
+  while (fr != std::string::npos) {
+    auto to = s.find("*/", fr + 2);
+    if (to == std::string::npos) {
+      throw std::runtime_error{"no matching */ for annotation comments"};
+    }
+    s.erase(fr, to - fr + 2);
+    fr = s.find("/*", fr);
+  }
+  // strip cpp-style comments
+  s.replace(
+      s.begin(),
+      s.end(),
+      std::regex_replace(
+          s,
+          std::regex("//.*(?=$|\\n)"), /* simulate multiline regex */
+          ""));
+
+  // strip newlines
+  boost::algorithm::replace_all(s, "\n", " ");
+}
+
+namespace python {
+cached_properties::cached_properties(
+    std::string cpp_template, std::string type, std::string flat_name)
+    : cpp_template_(std::move(cpp_template)),
+      cpp_type_(std::move(type)),
+      flat_name_(std::move(flat_name)) {
+  strip_cpp_comments_and_newlines(cpp_type_);
+}
+
+std::string cached_properties::to_cython_template() const {
+  // handle special built-ins first:
+  if (cpp_template_ == "std::vector") {
+    return "vector";
+  } else if (cpp_template_ == "std::set") {
+    return "cset";
+  } else if (cpp_template_ == "std::map") {
+    return "cmap";
+  }
+  // then default handling:
+  return boost::algorithm::replace_all_copy(cpp_template_, "::", "_");
+}
+
+std::string cached_properties::to_cython_type() const {
+  if (cpp_type_ == "") {
+    return "";
+  }
+  std::string cython_type = cpp_type_;
+  boost::algorithm::replace_all(cython_type, "::", "_");
+  boost::algorithm::replace_all(cython_type, "<", "_");
+  boost::algorithm::replace_all(cython_type, ">", "");
+  boost::algorithm::replace_all(cython_type, " ", "");
+  boost::algorithm::replace_all(cython_type, ", ", "_");
+  boost::algorithm::replace_all(cython_type, ",", "_");
+  return cython_type;
+}
+
+bool cached_properties::is_default_template(
+    const apache::thrift::compiler::t_type* type) const {
+  return (!type->is_container() && cpp_template_ == "") ||
+      (type->is_list() && cpp_template_ == "std::vector") ||
+      (type->is_set() && cpp_template_ == "std::set") ||
+      (type->is_map() && cpp_template_ == "std::map");
+}
+
+void cached_properties::set_flat_name(
+    const apache::thrift::compiler::t_program* this_prog,
+    const apache::thrift::compiler::t_type* type,
+    const std::string& extra) {
+  std::string custom_prefix;
+  if (!is_default_template(type)) {
+    custom_prefix = to_cython_template() + "__";
+  } else if (cpp_type_ != "") {
+    custom_prefix = to_cython_type() + "__";
+  }
+  const t_program* type_program = type->program();
+  if (type_program && type_program != this_prog) {
+    custom_prefix += type_program->name() + "_";
+  }
+  custom_prefix += extra;
+  flat_name_ = std::move(custom_prefix);
+}
+
+} // namespace python
 } // namespace apache::thrift::compiler
diff --git a/thrift/compiler/generate/python/util.h b/thrift/compiler/generate/python/util.h
index 827c63a2812..a06ab857a74 100644
--- a/thrift/compiler/generate/python/util.h
+++ b/thrift/compiler/generate/python/util.h
@@ -14,9 +14,14 @@
  * limitations under the License.
  */
 
+#include <map>
+#include <string>
 #include <string_view>
+#include <unordered_set>
 
+#include <thrift/compiler/ast/t_program.h>
 #include <thrift/compiler/ast/t_type.h>
+#include <thrift/compiler/lib/uri.h>
 
 namespace apache::thrift::compiler {
 
@@ -32,4 +37,90 @@ bool is_type_iobuf(std::string_view name);
 
 bool is_type_iobuf(const t_type* type);
 
+std::vector<std::string> get_py3_namespace(const t_program* prog);
+
+std::string get_py3_namespace_with_name_and_prefix(
+    const t_program* prog,
+    const std::string& prefix,
+    const std::string& sep = ".");
+
+inline const std::unordered_set<std::string>& get_python_reserved_names() {
+  static const std::unordered_set<std::string> keywords = {
+      "False",  "None",    "True",    "and",      "as",       "assert", "async",
+      "await",  "break",   "class",   "continue", "def",      "del",    "elif",
+      "else",   "except",  "finally", "for",      "from",     "global", "if",
+      "import", "in",      "is",      "lambda",   "nonlocal", "not",    "or",
+      "pass",   "raise",   "return",  "try",      "while",    "with",   "yield",
+      "cdef",   "cimport", "cpdef",   "cppclass", "ctypedef",
+  };
+  return keywords;
+}
+
+/**
+ * strip comments and newlines off cpp annotation text
+ */
+void strip_cpp_comments_and_newlines(std::string& s);
+
+namespace python {
+
+class cached_properties {
+ public:
+  cached_properties(
+      std::string cpp_template, std::string type, std::string flat_name);
+
+  const std::string& cpp_template() const { return cpp_template_; }
+  const std::string& cpp_type() const { return cpp_type_; }
+  const std::string& flat_name() const { return flat_name_; }
+
+  std::string to_cython_template() const;
+
+  std::string to_cython_type() const;
+
+  bool is_default_template(const t_type* type) const;
+
+  void set_flat_name(
+      const t_program* this_prog, const t_type* type, const std::string& extra);
+
+ private:
+  const std::string cpp_template_;
+  std::string cpp_type_;
+  std::string flat_name_;
+};
+
+template <class T>
+std::string get_py3_name(const T& node) {
+  // Reserved Cython / Python keywords that are not blocked by thrift grammer
+  // TODO: get rid of this list and force users to rename explicitly
+  static const std::unordered_set<std::string> cython_keywords = {
+      "DEF",
+      "ELIF",
+      "ELSE",
+      "IF",
+      "cdef",
+      "cimport",
+      "cpdef",
+      "cppclass",
+      "ctypedef",
+  };
+
+  if (const t_const* annot =
+          node.find_structured_annotation_or_null(kPythonNameUri)) {
+    if (auto name =
+            annot->get_value_from_structured_annotation_or_null("name")) {
+      return name->get_string();
+    }
+  }
+  if (const auto* name = node.find_annotation_or_null("py3.name")) {
+    return *name;
+  }
+  const auto& name = node.get_name();
+  const auto& python_keywords = get_python_reserved_names();
+  if (cython_keywords.find(name) != cython_keywords.end() ||
+      python_keywords.find(name) != python_keywords.end()) {
+    return name + "_";
+  }
+  return name;
+}
+
+} // namespace python
 } // namespace apache::thrift::compiler
diff --git a/thrift/compiler/generate/t_mstch_py3_generator.cc b/thrift/compiler/generate/t_mstch_py3_generator.cc
index b2b1247b1b2..7ef01ddde77 100644
--- a/thrift/compiler/generate/t_mstch_py3_generator.cc
+++ b/thrift/compiler/generate/t_mstch_py3_generator.cc
@@ -26,7 +26,7 @@
 #include <thrift/compiler/generate/cpp/reference_type.h>
 #include <thrift/compiler/generate/cpp/util.h>
 #include <thrift/compiler/generate/mstch_objects.h>
-#include <thrift/compiler/generate/py3/util.h>
+#include <thrift/compiler/generate/python/util.h>
 #include <thrift/compiler/generate/t_mstch_generator.h>
 #include <thrift/compiler/lib/uri.h>
 
@@ -577,14 +577,14 @@ class py3_mstch_function : public mstch_function {
 
 class py3_mstch_type : public mstch_type {
  public:
-  using CachedProperties = apache::thrift::compiler::py3::CachedProperties;
+  using cached_properties = apache::thrift::compiler::python::cached_properties;
 
   struct data {
     const t_program* program;
-    std::unordered_map<const t_type*, CachedProperties>* cache;
+    std::unordered_map<const t_type*, cached_properties>* cache;
   };
 
-  CachedProperties& get_cached_props(const t_type* type, const data& d);
+  cached_properties& get_cached_props(const t_type* type, const data& d);
 
   py3_mstch_type(
       const t_type* type,
@@ -644,19 +644,19 @@ class py3_mstch_type : public mstch_type {
     return fmt::format("_{}", fmt::join(get_type_py3_namespace(), "_"));
   }
 
-  mstch::node flatName() { return cached_props_.flatName(); }
+  mstch::node flatName() { return cached_props_.flat_name(); }
 
   mstch::node cppNamespaces() {
     return create_string_array(get_type_cpp2_namespace());
   }
 
-  mstch::node cppTemplate() { return cached_props_.cppTemplate(); }
+  mstch::node cppTemplate() { return cached_props_.cpp_template(); }
 
   mstch::node cythonTemplate() { return to_cython_template(); }
 
   mstch::node isDefaultTemplate() { return is_default_template(); }
 
-  mstch::node cppType() { return cached_props_.cppType(); }
+  mstch::node cppType() { return cached_props_.cpp_type(); }
 
   mstch::node cythonType() { return to_cython_type(); }
 
@@ -697,7 +697,7 @@ class py3_mstch_type : public mstch_type {
         resolved_type_->is_exception();
   }
 
-  const std::string& get_flat_name() const { return cached_props_.flatName(); }
+  const std::string& get_flat_name() const { return cached_props_.flat_name(); }
 
   void set_flat_name(const std::string& extra) {
     cached_props_.set_flat_name(prog_, type_, extra);
@@ -707,7 +707,7 @@ class py3_mstch_type : public mstch_type {
     return cached_props_.is_default_template(type_);
   }
 
-  bool has_custom_cpp_type() const { return cached_props_.cppType() != ""; }
+  bool has_custom_cpp_type() const { return cached_props_.cpp_type() != ""; }
 
  protected:
   const t_program* get_type_program() const {
@@ -753,10 +753,10 @@ class py3_mstch_type : public mstch_type {
 
   bool has_cython_type() const { return !type_->is_container(); }
 
-  bool is_iobuf() const { return cached_props_.cppType() == "folly::IOBuf"; }
+  bool is_iobuf() const { return cached_props_.cpp_type() == "folly::IOBuf"; }
 
   bool is_iobuf_ref() const {
-    return cached_props_.cppType() == "std::unique_ptr<folly::IOBuf>";
+    return cached_props_.cpp_type() == "std::unique_ptr<folly::IOBuf>";
   }
 
   bool is_flexible_binary() const {
@@ -764,8 +764,8 @@ class py3_mstch_type : public mstch_type {
         !is_iobuf_ref() &&
         // We know that folly::fbstring is completely substitutable for
         // std::string and it's a common-enough type to special-case:
-        cached_props_.cppType() != "folly::fbstring" &&
-        cached_props_.cppType() != "::folly::fbstring";
+        cached_props_.cpp_type() != "folly::fbstring" &&
+        cached_props_.cpp_type() != "::folly::fbstring";
   }
 
   bool has_custom_type_behavior() const {
@@ -773,7 +773,7 @@ class py3_mstch_type : public mstch_type {
   }
 
   const t_program* prog_;
-  CachedProperties& cached_props_;
+  cached_properties& cached_props_;
 };
 
 class py3_mstch_struct : public mstch_struct {
@@ -837,7 +837,7 @@ class py3_mstch_struct : public mstch_struct {
   mstch::node exceptionMessage() {
     const auto* message_field =
         dynamic_cast<const t_exception&>(*struct_).get_message_field();
-    return message_field ? py3::get_py3_name(*message_field) : "";
+    return message_field ? python::get_py3_name(*message_field) : "";
   }
 
   mstch::node py3_fields() { return make_mstch_fields(py3_fields_); }
@@ -887,7 +887,7 @@ class py3_mstch_field : public mstch_field {
       mstch_element_position pos,
       const field_generator_context* field_context)
       : mstch_field(field, ctx, pos, field_context),
-        pyName_(py3::get_py3_name(*field)),
+        pyName_(python::get_py3_name(*field)),
         cppName_(cpp2::get_name(field)) {
     register_cached_methods(
         this,
@@ -1038,12 +1038,12 @@ class py3_mstch_enum_value : public mstch_enum_value {
         });
   }
 
-  mstch::node pyName() { return py3::get_py3_name(*enum_value_); }
+  mstch::node pyName() { return python::get_py3_name(*enum_value_); }
 
   mstch::node cppName() { return cpp2::get_name(enum_value_); }
 
   mstch::node hasPyName() {
-    return py3::get_py3_name(*enum_value_) != enum_value_->get_name();
+    return python::get_py3_name(*enum_value_) != enum_value_->get_name();
   }
 };
 
@@ -1296,11 +1296,11 @@ class t_mstch_py3_generator : public t_mstch_generator {
   std::filesystem::path package_to_path();
 
   std::filesystem::path generateRootPath_;
-  std::unordered_map<const t_type*, py3_mstch_type::CachedProperties>
+  std::unordered_map<const t_type*, py3_mstch_type::cached_properties>
       type_props_cache_;
 };
 
-py3_mstch_type::CachedProperties& py3_mstch_type::get_cached_props(
+py3_mstch_type::cached_properties& py3_mstch_type::get_cached_props(
     const t_type* type, const data& d) {
   auto true_type = type->get_true_type();
   auto it = d.cache->find(true_type);
@@ -1308,7 +1308,7 @@ py3_mstch_type::CachedProperties& py3_mstch_type::get_cached_props(
     it = d.cache
              ->emplace(
                  true_type,
-                 py3_mstch_type::CachedProperties{
+                 py3_mstch_type::cached_properties{
                      get_cpp_template(*true_type),
                      fmt::to_string(cpp2::get_type(true_type)),
                      {}})
diff --git a/thrift/compiler/generate/t_mstch_pyi_generator.cc b/thrift/compiler/generate/t_mstch_pyi_generator.cc
index 74eafd2202a..64daa3e45a1 100644
--- a/thrift/compiler/generate/t_mstch_pyi_generator.cc
+++ b/thrift/compiler/generate/t_mstch_pyi_generator.cc
@@ -28,7 +28,7 @@
 #include <thrift/compiler/ast/t_type.h>
 #include <thrift/compiler/generate/common.h>
 #include <thrift/compiler/generate/mstch_objects.h>
-#include <thrift/compiler/generate/py3/util.h>
+#include <thrift/compiler/generate/python/util.h>
 #include <thrift/compiler/generate/t_mstch_generator.h>
 
 namespace apache::thrift::compiler {
diff --git a/thrift/compiler/generate/t_mstch_python_capi_generator.cc b/thrift/compiler/generate/t_mstch_python_capi_generator.cc
index f867bd4778e..453d9d1cdf8 100644
--- a/thrift/compiler/generate/t_mstch_python_capi_generator.cc
+++ b/thrift/compiler/generate/t_mstch_python_capi_generator.cc
@@ -31,7 +31,6 @@
 #include <thrift/compiler/generate/cpp/name_resolver.h>
 #include <thrift/compiler/generate/cpp/util.h>
 #include <thrift/compiler/generate/mstch_objects.h>
-#include <thrift/compiler/generate/py3/util.h>
 #include <thrift/compiler/generate/python/util.h>
 #include <thrift/compiler/generate/t_mstch_generator.h>
 #include <thrift/compiler/lib/uri.h>
@@ -466,7 +465,7 @@ class python_capi_mstch_struct : public mstch_struct {
         });
   }
 
-  mstch::node py_name() { return py3::get_py3_name(*struct_); }
+  mstch::node py_name() { return python::get_py3_name(*struct_); }
 
   mstch::node tuple_positions() {
     std::vector<std::pair<int, int>> index_keys;
@@ -625,7 +624,7 @@ class python_capi_mstch_field : public mstch_field {
       mstch_element_position pos,
       const field_generator_context* field_context)
       : mstch_field(field, ctx, pos, field_context),
-        py_name_(py3::get_py3_name(*field)) {
+        py_name_(python::get_py3_name(*field)) {
     register_cached_methods(
         this,
         {
diff --git a/thrift/compiler/generate/t_mstch_python_generator.cc b/thrift/compiler/generate/t_mstch_python_generator.cc
index 6bb539c52ba..ba24d95572b 100644
--- a/thrift/compiler/generate/t_mstch_python_generator.cc
+++ b/thrift/compiler/generate/t_mstch_python_generator.cc
@@ -33,7 +33,6 @@
 #include <thrift/compiler/detail/mustache/mstch.h>
 #include <thrift/compiler/generate/common.h>
 #include <thrift/compiler/generate/mstch_objects.h>
-#include <thrift/compiler/generate/py3/util.h>
 #include <thrift/compiler/generate/python/util.h>
 #include <thrift/compiler/generate/t_mstch_generator.h>
 #include <thrift/compiler/lib/uri.h>
@@ -744,7 +743,7 @@ class python_mstch_struct : public mstch_struct {
         });
   }
 
-  mstch::node py_name() { return py3::get_py3_name(*struct_); }
+  mstch::node py_name() { return python::get_py3_name(*struct_); }
 
   mstch::node fields_ordered_by_id() {
     std::vector<const t_field*> fields = struct_->fields().copy();
@@ -761,7 +760,7 @@ class python_mstch_struct : public mstch_struct {
   mstch::node exception_message() {
     const auto* message_field =
         dynamic_cast<const t_exception&>(*struct_).get_message_field();
-    return message_field ? py3::get_py3_name(*message_field) : "";
+    return message_field ? python::get_py3_name(*message_field) : "";
   }
 
   mstch::node adapter() {
@@ -786,7 +785,7 @@ class python_mstch_field : public mstch_field {
       mstch_element_position pos,
       const field_generator_context* field_context)
       : mstch_field(field, ctx, pos, field_context),
-        py_name_(py3::get_py3_name(*field)),
+        py_name_(python::get_py3_name(*field)),
         adapter_annotation_(find_structured_adapter_annotation(*field)),
         transitive_adapter_annotation_(
             get_transitive_annotation_of_adapter_or_null(*field)) {
@@ -899,7 +898,7 @@ class python_mstch_enum_value : public mstch_enum_value {
         });
   }
 
-  mstch::node py_name() { return py3::get_py3_name(*enum_value_); }
+  mstch::node py_name() { return python::get_py3_name(*enum_value_); }
 };
 
 // Generator-specific validator that enforces "name" and "value" are not used
@@ -1123,7 +1122,7 @@ class python_mstch_const_value : public mstch_const_value {
 
   mstch::node py3_enum_value_name() {
     if (const_value_->is_enum() && const_value_->get_enum_value() != nullptr) {
-      return py3::get_py3_name(*const_value_->get_enum_value());
+      return python::get_py3_name(*const_value_->get_enum_value());
     }
     return mstch::node();
   }
diff --git a/thrift/compiler/generate/t_py_generator.cc b/thrift/compiler/generate/t_py_generator.cc
index dc6a09b8a4d..b163c9f610e 100644
--- a/thrift/compiler/generate/t_py_generator.cc
+++ b/thrift/compiler/generate/t_py_generator.cc
@@ -32,7 +32,7 @@
 #include <thrift/compiler/ast/t_typedef.h>
 #include <thrift/compiler/detail/system.h>
 #include <thrift/compiler/generate/common.h>
-#include <thrift/compiler/generate/py3/util.h>
+#include <thrift/compiler/generate/python/util.h>
 #include <thrift/compiler/generate/t_concat_generator.h>
 #include <thrift/compiler/generate/t_generator.h>
 
diff --git a/thrift/compiler/test/generate_common_test.cc b/thrift/compiler/test/generate_common_test.cc
index 19ea5f1bd4d..17f4b5fc2eb 100644
--- a/thrift/compiler/test/generate_common_test.cc
+++ b/thrift/compiler/test/generate_common_test.cc
@@ -20,7 +20,7 @@
 #include <folly/portability/GTest.h>
 
 #include <thrift/compiler/generate/common.h>
-#include <thrift/compiler/generate/py3/util.h>
+#include <thrift/compiler/generate/python/util.h>
 
 namespace apache::thrift::compiler {
 
diff --git a/thrift/compiler/test/py3_util_test.cc b/thrift/compiler/test/python_util_test.cc
similarity index 73%
rename from thrift/compiler/test/py3_util_test.cc
rename to thrift/compiler/test/python_util_test.cc
index 35c958592c6..35a6c08b557 100644
--- a/thrift/compiler/test/py3_util_test.cc
+++ b/thrift/compiler/test/python_util_test.cc
@@ -18,19 +18,21 @@
 
 #include <thrift/compiler/ast/t_field.h>
 #include <thrift/compiler/ast/t_primitive_type.h>
-#include <thrift/compiler/generate/py3/util.h>
+#include <thrift/compiler/generate/python/util.h>
 
 using namespace apache::thrift::compiler;
 
 TEST(UtilTest, get_py3_name) {
   EXPECT_EQ(
-      "foo", py3::get_py3_name(t_field(t_primitive_type::t_i32(), "foo")));
+      "foo", python::get_py3_name(t_field(t_primitive_type::t_i32(), "foo")));
   EXPECT_EQ(
-      "True_", py3::get_py3_name(t_field(t_primitive_type::t_i32(), "True")));
+      "True_",
+      python::get_py3_name(t_field(t_primitive_type::t_i32(), "True")));
   EXPECT_EQ(
-      "cpdef_", py3::get_py3_name(t_field(t_primitive_type::t_i32(), "cpdef")));
+      "cpdef_",
+      python::get_py3_name(t_field(t_primitive_type::t_i32(), "cpdef")));
 
   t_field f(t_primitive_type::t_i32(), "foo");
   f.set_annotation("py3.name", "bar");
-  EXPECT_EQ("bar", py3::get_py3_name(f));
+  EXPECT_EQ("bar", python::get_py3_name(f));
 }