From b974229a1e35ac2c55cbaf0ee3d78dc94e4b68bf Mon Sep 17 00:00:00 2001 From: Nanshu Chen Date: Thu, 20 Aug 2020 08:44:42 -0700 Subject: [PATCH] refactor Enum code generation Summary: Changed the way how enums generated in thrift-py3: 1. Use C++ map to store name to unique Enum Python instances cache 2. Dynamically find instances from cache (or create one and add to cache) instead of populating all instances at module load time 3. use `__getattr__` and `__getitem__` instead of code-gen all the getters Reviewed By: asp2insp Differential Revision: D23182622 fbshipit-source-id: 75baef997ee2d604b4ef7606f282cfc3306208ac --- .../generate/t_mstch_py3_generator.cc | 25 +- .../CythonFieldValueForAssignment.mustache | 4 +- .../py3/CythonPythonToCppArg.mustache | 2 +- .../py3/CythonPythonToCppItem.mustache | 2 +- .../py3/CythonPythonToCppKey.mustache | 2 +- .../py3/CythonUnionAssignField.mustache | 2 +- .../py3/services/CythonReturnValue.mustache | 2 +- .../generate/templates/py3/types.h.mustache | 60 ++ .../generate/templates/py3/types.pxd.mustache | 9 +- .../generate/templates/py3/types.pyi.mustache | 4 +- .../generate/templates/py3/types.pyx.mustache | 6 +- .../templates/py3/types/enum.mustache | 198 +--- .../templates/py3/types/enumDefs.mustache | 5 - .../py3/types/unionTypeEnum.mustache | 108 +-- .../basic-annotations/gen-py3/module/types.h | 22 + .../gen-py3/module/types.pxd | 14 +- .../gen-py3/module/types.pyx | 110 +-- .../basic-enum/gen-py3/module/types.h | 44 + .../test/fixtures/enumstrict/module/types.h | 44 + .../test/fixtures/enumstrict/module/types.pxd | 51 +- .../test/fixtures/enumstrict/module/types.pyx | 393 +------- .../gen-py3/module/types.h | 22 + .../gen-py3/module/types.pxd | 13 +- .../gen-py3/module/types.pyx | 104 +- .../fixtures/basic/gen-py3/module/types.h | 32 + .../fixtures/basic/gen-py3/module/types.pxd | 13 +- .../fixtures/basic/gen-py3/module/types.pyx | 210 +--- .../complex-union/gen-py3/module/types.h | 71 ++ .../complex-union/gen-py3/module/types.pxd | 2 + .../complex-union/gen-py3/module/types.pyx | 598 ++---------- .../fixtures/constants/gen-py3/module/types.h | 64 ++ .../constants/gen-py3/module/types.pxd | 37 +- .../constants/gen-py3/module/types.pyx | 507 ++-------- .../empty-struct/gen-py3/module/types.h | 21 + .../empty-struct/gen-py3/module/types.pxd | 2 + .../empty-struct/gen-py3/module/types.pyx | 89 +- .../exceptions/gen-py3/module/types.h | 11 + .../exceptions/gen-py3/module/types.pxd | 2 + .../exceptions/gen-py3/module/types.pyx | 7 +- .../includes/gen-py3/includes/types.h | 11 + .../includes/gen-py3/includes/types.pxd | 2 + .../includes/gen-py3/includes/types.pyx | 7 +- .../gen-py3/matching_struct_names/types.h | 11 + .../gen-py3/matching_struct_names/types.pxd | 2 + .../gen-py3/matching_struct_names/types.pyx | 7 +- .../fixtures/includes/gen-py3/module/types.h | 11 + .../includes/gen-py3/module/types.pxd | 2 + .../includes/gen-py3/module/types.pyx | 7 +- .../fixtures/includes/gen-py3/service/types.h | 11 + .../includes/gen-py3/service/types.pxd | 2 + .../includes/gen-py3/service/types.pyx | 7 +- .../includes/gen-py3/transitive/types.h | 11 + .../includes/gen-py3/transitive/types.pxd | 2 + .../includes/gen-py3/transitive/types.pyx | 7 +- .../inheritance/gen-py3/module/types.h | 11 + .../inheritance/gen-py3/module/types.pxd | 2 + .../inheritance/gen-py3/module/types.pyx | 7 +- .../test/fixtures/list/gen-py3/module/types.h | 11 + .../fixtures/list/gen-py3/module/types.pxd | 2 + .../fixtures/list/gen-py3/module/types.pyx | 7 +- .../mcpp2-compare/gen-py3/includes/types.h | 22 + .../mcpp2-compare/gen-py3/includes/types.pxd | 13 +- .../mcpp2-compare/gen-py3/includes/types.pyx | 104 +- .../mcpp2-compare/gen-py3/module/clients.pyx | 4 +- .../mcpp2-compare/gen-py3/module/services.pyx | 6 +- .../mcpp2-compare/gen-py3/module/types.h | 85 ++ .../mcpp2-compare/gen-py3/module/types.pxd | 48 +- .../mcpp2-compare/gen-py3/module/types.pyx | 897 +++--------------- .../fixtures/namespace/gen-py3/extend/types.h | 11 + .../namespace/gen-py3/hsmodule/types.h | 11 + .../namespace/gen-py3/hsmodule/types.pxd | 2 + .../namespace/gen-py3/hsmodule/types.pyx | 7 +- .../fixtures/namespace/gen-py3/module/types.h | 11 + .../my/namespacing/extend/test/extend/types.h | 11 + .../namespacing/extend/test/extend/types.pxd | 2 + .../namespacing/extend/test/extend/types.pyx | 7 +- .../my/namespacing/test/module/module/types.h | 11 + .../namespacing/test/module/module/types.pxd | 2 + .../namespacing/test/module/module/types.pyx | 7 +- .../fixtures/optionals/gen-py3/module/types.h | 22 + .../optionals/gen-py3/module/types.pxd | 14 +- .../optionals/gen-py3/module/types.pyx | 118 +-- .../fixtures/params/gen-py3/module/types.h | 11 + .../fixtures/params/gen-py3/module/types.pxd | 2 + .../fixtures/params/gen-py3/module/types.pyx | 7 +- .../test/fixtures/py3/gen-py3/empty/types.h | 11 + .../test/fixtures/py3/gen-py3/empty/types.pxd | 2 + .../test/fixtures/py3/gen-py3/empty/types.pyx | 7 +- .../fixtures/py3/gen-py3/module/clients.pyx | 2 +- .../fixtures/py3/gen-py3/module/services.pyx | 2 +- .../test/fixtures/py3/gen-py3/module/types.h | 44 + .../fixtures/py3/gen-py3/module/types.pxd | 29 +- .../fixtures/py3/gen-py3/module/types.pyx | 378 ++------ .../qualified/gen-py3/module0/types.h | 22 + .../qualified/gen-py3/module0/types.pxd | 14 +- .../qualified/gen-py3/module0/types.pyx | 118 +-- .../qualified/gen-py3/module1/types.h | 22 + .../qualified/gen-py3/module1/types.pxd | 14 +- .../qualified/gen-py3/module1/types.pyx | 118 +-- .../qualified/gen-py3/module2/types.h | 11 + .../qualified/gen-py3/module2/types.pxd | 2 + .../qualified/gen-py3/module2/types.pyx | 7 +- .../test/fixtures/refs/gen-py3/module/types.h | 32 + .../fixtures/refs/gen-py3/module/types.pxd | 13 +- .../fixtures/refs/gen-py3/module/types.pyx | 195 +--- .../fixtures/req-opt/gen-py3/module/types.h | 11 + .../fixtures/req-opt/gen-py3/module/types.pxd | 2 + .../fixtures/req-opt/gen-py3/module/types.pyx | 7 +- .../test/fixtures/sink/gen-py3/module/types.h | 11 + .../fixtures/sink/gen-py3/module/types.pxd | 2 + .../fixtures/sink/gen-py3/module/types.pyx | 7 +- .../fixtures/stream/gen-py3/module/types.h | 11 + .../fixtures/stream/gen-py3/module/types.pxd | 2 + .../fixtures/stream/gen-py3/module/types.pyx | 7 +- .../gen-py3/module/types.h | 22 + .../gen-py3/module/types.pxd | 14 +- .../gen-py3/module/types.pyx | 112 +-- .../fixtures/types/gen-py3/include/types.h | 11 + .../fixtures/types/gen-py3/include/types.pxd | 2 + .../fixtures/types/gen-py3/include/types.pyx | 7 +- .../fixtures/types/gen-py3/module/types.h | 65 ++ .../fixtures/types/gen-py3/module/types.pxd | 50 +- .../fixtures/types/gen-py3/module/types.pyx | 516 ++-------- thrift/lib/py3/enums.cpp | 150 +++ thrift/lib/py3/enums.h | 195 ++++ thrift/lib/py3/std_libcpp.pxd | 20 + thrift/lib/py3/test/unions.py | 2 +- thrift/lib/py3/types.pxd | 78 +- thrift/lib/py3/types.pyi | 7 +- thrift/lib/py3/types.pyx | 243 ++++- 130 files changed, 2611 insertions(+), 4473 deletions(-) create mode 100644 thrift/compiler/generate/templates/py3/types.h.mustache create mode 100644 thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/basic-enum/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.h create mode 100644 thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/basic/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/constants/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/includes/gen-py3/includes/types.h create mode 100644 thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.h create mode 100644 thrift/compiler/test/fixtures/includes/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/includes/gen-py3/service/types.h create mode 100644 thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.h create mode 100644 thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/list/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.h create mode 100644 thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/namespace/gen-py3/extend/types.h create mode 100644 thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.h create mode 100644 thrift/compiler/test/fixtures/namespace/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.h create mode 100644 thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.h create mode 100644 thrift/compiler/test/fixtures/optionals/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/params/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/py3/gen-py3/empty/types.h create mode 100644 thrift/compiler/test/fixtures/py3/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.h create mode 100644 thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.h create mode 100644 thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.h create mode 100644 thrift/compiler/test/fixtures/refs/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/sink/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/stream/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.h create mode 100644 thrift/compiler/test/fixtures/types/gen-py3/include/types.h create mode 100644 thrift/compiler/test/fixtures/types/gen-py3/module/types.h create mode 100644 thrift/lib/py3/enums.cpp create mode 100644 thrift/lib/py3/enums.h diff --git a/thrift/compiler/generate/t_mstch_py3_generator.cc b/thrift/compiler/generate/t_mstch_py3_generator.cc index 3e81abba323..87cdd14e48a 100644 --- a/thrift/compiler/generate/t_mstch_py3_generator.cc +++ b/thrift/compiler/generate/t_mstch_py3_generator.cc @@ -778,7 +778,7 @@ class mstch_py3_field : public mstch_field { {"field:isset?", &mstch_py3_field::isSet}, {"field:cppName", &mstch_py3_field::cppName}, {"field:hasModifiedName?", &mstch_py3_field::hasModifiedName}, - {"field:enumSafeName", &mstch_py3_field::enumSafeName}, + {"field:hasPyName?", &mstch_py3_field::hasPyName}, }); } @@ -837,11 +837,8 @@ class mstch_py3_field : public mstch_field { return pyName_ != cppName_; } - mstch::node enumSafeName() { - if (pyName_ == "name" || pyName_ == "value") { - return pyName_ + "_"; - } - return pyName_; + mstch::node hasPyName() { + return pyName_ != field_->get_name(); } bool has_default_value() { @@ -1010,7 +1007,7 @@ class mstch_py3_enum_value : public mstch_enum_value { { {"enumValue:py_name", &mstch_py3_enum_value::pyName}, {"enumValue:cppName", &mstch_py3_enum_value::cppName}, - {"enumValue:enumSafeName", &mstch_py3_enum_value::enumSafeName}, + {"enumValue:hasPyName?", &mstch_py3_enum_value::hasPyName}, }); } @@ -1022,12 +1019,8 @@ class mstch_py3_enum_value : public mstch_enum_value { return get_cppname(*enm_value_); } - mstch::node enumSafeName() { - auto pyName = py3::get_py3_name(*enm_value_); - if (pyName == "name" || pyName == "value") { - return pyName + "_"; - } - return pyName; + mstch::node hasPyName() { + return py3::get_py3_name(*enm_value_) != enm_value_->get_name(); } }; @@ -1456,13 +1449,16 @@ void t_mstch_py3_generator::generate_module(ModuleType moduleType) { if (moduleType != ModuleType::REFLECTIONS) { exts.push_back(".pyi"); } + if (moduleType == ModuleType::TYPES) { + exts.push_back(".h"); + } for (auto ext : exts) { render_to_file( nodePtr, module + ext, generateRootPath_ / name / (module + ext)); } + auto cpp_path = boost::filesystem::path{name}; if (moduleType == ModuleType::CLIENTS || moduleType == ModuleType::SERVICES) { auto basename = module + "_wrapper"; - auto cpp_path = boost::filesystem::path{name}; for (auto ext : {".h", ".cpp"}) { render_to_file(nodePtr, basename + ext, cpp_path / (basename + ext)); } @@ -1474,6 +1470,7 @@ void t_mstch_py3_generator::generate_module(ModuleType moduleType) { } if (moduleType == ModuleType::TYPES) { + render_to_file(nodePtr, "types.h", cpp_path / "types.h"); programNodePtr->setTypeContext(false); for (auto ext : {".pxd", ".pyx"}) { const auto filename = std::string{"types_reflection"} + ext; diff --git a/thrift/compiler/generate/templates/py3/CythonFieldValueForAssignment.mustache b/thrift/compiler/generate/templates/py3/CythonFieldValueForAssignment.mustache index 8be03e2139c..9ec71896505 100644 --- a/thrift/compiler/generate/templates/py3/CythonFieldValueForAssignment.mustache +++ b/thrift/compiler/generate/templates/py3/CythonFieldValueForAssignment.mustache @@ -50,9 +50,7 @@ on a struct. }}{{#type:string?}}.encode('utf-8'))){{/type:string?}}{{! }}{{#type:binary?}})){{/type:binary?}}{{! }}{{/type:base?}}{{! -}}{{#type:enum?}}{{! - }}{{> types/CythonPythonType}}_to_cpp({{field:py_name}}){{! -}}{{/type:enum?}}{{! +}}{{#type:enum?}}<{{> types/CythonCppType}}>{{field:py_name}}{{/type:enum?}}{{! }}{{#type:struct?}}{{! }}deref((<{{> types/CythonPythonType }}?> {{field:py_name}})._cpp_obj){{! }}{{/type:struct?}}{{! diff --git a/thrift/compiler/generate/templates/py3/CythonPythonToCppArg.mustache b/thrift/compiler/generate/templates/py3/CythonPythonToCppArg.mustache index 6872a74e740..ad35a7fc7e4 100644 --- a/thrift/compiler/generate/templates/py3/CythonPythonToCppArg.mustache +++ b/thrift/compiler/generate/templates/py3/CythonPythonToCppArg.mustache @@ -44,5 +44,5 @@ This template assumes that the Python object is in a variable named . }}{{#type:container?}}{{! }}deref((<{{> types/CythonPythonType}}>{{field:py_name}})._cpp_obj){{! }}{{/type:container?}}{{! -}}{{#type:enum}}{{> types/CythonPythonType}}_to_cpp({{field:py_name}}){{/type:enum}}{{! +}}{{#type:enum?}}<{{> types/CythonCppType}}>{{field:py_name}}{{/type:enum?}}{{! }}{{/type:hasCustomTypeBehavior?}} diff --git a/thrift/compiler/generate/templates/py3/CythonPythonToCppItem.mustache b/thrift/compiler/generate/templates/py3/CythonPythonToCppItem.mustache index 4a2c80628fc..d31ae49749b 100644 --- a/thrift/compiler/generate/templates/py3/CythonPythonToCppItem.mustache +++ b/thrift/compiler/generate/templates/py3/CythonPythonToCppItem.mustache @@ -50,5 +50,5 @@ key, include the parallel CythonPythonToCppKey file instead. }}{{#type:container?}}{{! }}deref((<{{> types/CythonPythonType}}>item)._cpp_obj){{! }}{{/type:container?}}{{! -}}{{#type:enum}}{{> types/CythonPythonType}}_to_cpp(item){{/type:enum}}{{! +}}{{#type:enum?}}<{{> types/CythonCppType}}>item{{/type:enum?}}{{! }}{{/type:hasCustomTypeBehavior?}} diff --git a/thrift/compiler/generate/templates/py3/CythonPythonToCppKey.mustache b/thrift/compiler/generate/templates/py3/CythonPythonToCppKey.mustache index cc737389107..31951a1c3d9 100644 --- a/thrift/compiler/generate/templates/py3/CythonPythonToCppKey.mustache +++ b/thrift/compiler/generate/templates/py3/CythonPythonToCppKey.mustache @@ -40,4 +40,4 @@ keys (conventionally used for sets, lists, and map values). }}{{#type:container?}}{{! }}deref((<{{> types/CythonPythonType}}>key)._cpp_obj){{! }}{{/type:container?}}{{! -}}{{#type:enum}}{{> types/CythonPythonType}}_to_cpp(key){{/type:enum}} +}}{{#type:enum?}}<{{> types/CythonCppType}}>key{{/type:enum?}} diff --git a/thrift/compiler/generate/templates/py3/CythonUnionAssignField.mustache b/thrift/compiler/generate/templates/py3/CythonUnionAssignField.mustache index aa56085f136..8852f7d748f 100644 --- a/thrift/compiler/generate/templates/py3/CythonUnionAssignField.mustache +++ b/thrift/compiler/generate/templates/py3/CythonUnionAssignField.mustache @@ -68,7 +68,7 @@ on a union. }}{{/type:binary?}}{{! }}{{#type:enum?}}{{! }}deref(c_inst).set_{{field:py_name}}({{! - }}{{> types/CythonPythonType}}_to_cpp({{field:py_name}})){{! + }}<{{> types/CythonCppType}}>{{field:py_name}}){{! }}{{/type:enum?}}{{! }}{{#type:struct?}}{{! }}deref(c_inst).set_{{field:py_name}}({{! diff --git a/thrift/compiler/generate/templates/py3/services/CythonReturnValue.mustache b/thrift/compiler/generate/templates/py3/services/CythonReturnValue.mustache index d4a998594a5..a8187d9fc18 100644 --- a/thrift/compiler/generate/templates/py3/services/CythonReturnValue.mustache +++ b/thrift/compiler/generate/templates/py3/services/CythonReturnValue.mustache @@ -73,5 +73,5 @@ to the client. }}{{^program:stack_arguments?}}){{/program:stack_arguments?}}{{! }}{{/type:container?}}{{! }}{{#type:void?}}c_unit{{/type:void?}}{{! -}}{{#type:enum}}{{> types/CythonPythonType}}_to_cpp(result){{/type:enum}}{{! +}}{{#type:enum?}}<{{> types/CythonCppType}}>result{{/type:enum?}}{{! }}{{/type:hasCustomTypeBehavior?}} diff --git a/thrift/compiler/generate/templates/py3/types.h.mustache b/thrift/compiler/generate/templates/py3/types.h.mustache new file mode 100644 index 00000000000..f9c5ca2437b --- /dev/null +++ b/thrift/compiler/generate/templates/py3/types.h.mustache @@ -0,0 +1,60 @@ +{{! + + Copyright (c) Facebook, Inc. and its 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. + +}}{{! + +C++ header to store py3 specific Enum and Union type enum data + +}} +{{> common/AutoGeneratedC}} + +#pragma once + +#include +#include "{{program:includePrefix}}gen-cpp2/{{program:name}}_types.h" +{{#program:enums}} + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + {{#program:cppNamespaces}}::{{value}}{{/program:cppNamespaces}}::{{enum:name}}>::namesmap() { + static const folly::Indestructible pairs { + { + {{#enum:values}}{{#enumValue:hasPyName?}} + {"{{enumValue:py_name}}", "{{enumValue:name}}"}, + {{/enumValue:hasPyName?}}{{/enum:values}} + } + }; + return *pairs; +} + +{{/program:enums}} +{{#program:structs}} +{{#struct:union?}} + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + {{#program:cppNamespaces}}::{{value}}{{/program:cppNamespaces}}::{{struct:name}}::Type>::namesmap() { + static const folly::Indestructible pairs { + { + {{#struct:fields}}{{#field:hasPyName?}} + {"{{field:py_name}}", "{{field:name}}"}, + {{/field:hasPyName?}}{{/struct:fields}} + } + }; + return *pairs; +} +{{/struct:union?}} +{{/program:structs}} diff --git a/thrift/compiler/generate/templates/py3/types.pxd.mustache b/thrift/compiler/generate/templates/py3/types.pxd.mustache index b4990d84424..11d9a586869 100644 --- a/thrift/compiler/generate/templates/py3/types.pxd.mustache +++ b/thrift/compiler/generate/templates/py3/types.pxd.mustache @@ -58,6 +58,8 @@ from thrift.py3.common cimport RpcOptions as __RpcOptions {{#program:includeNamespaces}} cimport {{#includeNamespace}}{{value}}.{{/includeNamespace}}types as _{{#includeNamespace}}{{value}}_{{/includeNamespace}}types {{/program:includeNamespaces}} +cdef extern from "{{program:includePrefix}}gen-py3/{{program:name}}/types.h": + pass {{#program:cppIncludes}} cdef extern from "{{.}}": @@ -76,11 +78,8 @@ cdef extern from "{{program:includePrefix}}gen-cpp2/{{program:name}}_types.h"{{! }} namespace "{{#program:cppNamespaces}}::{{value}}{{/program:cppNamespaces}}": {{/first?}} cdef cppclass c{{enum:name}} "::{{#program:cppNamespaces}}{{value}}::{{/program:cppNamespaces}}{{enum:name}}": - bint operator==(c{{enum:name}}&) - bint operator!=(c{{enum:name}}&) - {{#enum:values}} - c{{enum:name}} {{enum:name}}__{{enumValue:py_name}} "::{{#program:cppNamespaces}}{{value}}::{{/program:cppNamespaces}}{{enum:name}}::{{enumValue:cppName}}" - {{/enum:values}} + pass + {{/program:enums}} diff --git a/thrift/compiler/generate/templates/py3/types.pyi.mustache b/thrift/compiler/generate/templates/py3/types.pyi.mustache index 65ef2306b3b..a33e5f077ab 100644 --- a/thrift/compiler/generate/templates/py3/types.pyi.mustache +++ b/thrift/compiler/generate/templates/py3/types.pyi.mustache @@ -46,7 +46,7 @@ __property__ = property {{#program:enums}} class {{enum:name}}(thrift.py3.types.{{^enum:flags?}}Enum{{/enum:flags?}}{{#enum:flags?}}Flag{{/enum:flags?}}): {{#enum:values}} - {{enumValue:enumSafeName}}: {{enum:name}} = ... + {{enumValue:py_name}}: {{enum:name}} = ... {{/enum:values}} {{^enum:values}} pass @@ -100,7 +100,7 @@ class {{struct:name}}({{> types/PythonStructClass}}, _typing.Hashable{{^struct:u class Type(thrift.py3.types.Enum): EMPTY: {{struct:name}}.Type = ... {{#struct:fields}} - {{field:enumSafeName}}: {{struct:name}}.Type = ... + {{field:py_name}}: {{struct:name}}.Type = ... {{/struct:fields}} @staticmethod diff --git a/thrift/compiler/generate/templates/py3/types.pyx.mustache b/thrift/compiler/generate/templates/py3/types.pyx.mustache index fd5cc5a10de..c97d9da95ff 100644 --- a/thrift/compiler/generate/templates/py3/types.pyx.mustache +++ b/thrift/compiler/generate/templates/py3/types.pyx.mustache @@ -40,6 +40,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -51,6 +52,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -61,7 +66,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins {{#program:has_stream?}} diff --git a/thrift/compiler/generate/templates/py3/types/enum.mustache b/thrift/compiler/generate/templates/py3/types/enum.mustache index f77fa1b53c0..b2683674774 100644 --- a/thrift/compiler/generate/templates/py3/types/enum.mustache +++ b/thrift/compiler/generate/templates/py3/types/enum.mustache @@ -20,202 +20,44 @@ This is a template for creating compiled Enum and Flag pyx information }} {{#program:enums}} -cdef object __{{enum:name}}EnumInstances = None # Set[{{enum:name}}] -cdef object __{{enum:name}}EnumMembers = {} # Dict[str, {{enum:name}}] -cdef object __{{enum:name}}EnumUniqueValues = dict() # Dict[int, {{enum:name}}] + {{#enum:flags?}} -cdef object __{{enum:name}}EnumValueMapping = None # WeakMapping[Int, {{enum:name}}] +cdef __EnumFlagsData __{{enum:name}}_enum_data = __EnumFlagsData.create(thrift.py3.types.createEnumFlagsData[c{{enum:name}}](), {{enum:name}}) +{{/enum:flags?}}{{^enum:flags?}} +cdef __EnumData __{{enum:name}}_enum_data = __EnumData.create(thrift.py3.types.createEnumData[c{{enum:name}}](), {{enum:name}}) {{/enum:flags?}} + @__cython.internal @__cython.auto_pickle(False) -cdef class __{{enum:name}}Meta(type): - def __call__(cls, value): - cdef int cvalue - {{#enum:flags?}} - cdef bint invert = False - {{/enum:flags?}} - if isinstance(value, cls): - return value - if isinstance(value, int): - {{#enum:flags?}} - if value < 0: - invert = True - value = ~value - {{/enum:flags?}} - cvalue = value - {{#enum:values}} - {{^first?}}el{{/first?}}if cvalue == {{enumValue:value}}: - return {{#enum:flags?}}~{{enum:name}}.{{enumValue:enumSafeName}} if invert else {{/enum:flags?}}{{enum:name}}.{{enumValue:enumSafeName}} - {{#last?}} - {{#enum:flags?}} - item = __{{enum:name}}EnumValueMapping.get(value, None) - if item is None: - item = {{enum:name}}.__new__({{enum:name}}, value, None) - return ~item if invert else item - {{/enum:flags?}} - {{/last?}} - {{/enum:values}} - - raise ValueError(f'{value} is not a valid {{enum:name}}') - - def __getitem__(cls, name): - return __{{enum:name}}EnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - {{#enum:values}} - '{{enumValue:enumSafeName}}', - {{/enum:values}} - ] - - def __iter__(cls): - return iter(__{{enum:name}}EnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __{{enum:name}}EnumInstances +cdef class __{{enum:name}}Meta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__{{enum:name}}EnumInstances) + def __get_by_name(cls, str name): + return __{{enum:name}}_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __{{enum:name}}_enum_data.get_by_value(value) -{{#enum:values}}{{#first?}} -cdef __{{enum:name}}_unique_instance(int value, str name): - {{! Build up __memebers__ and maintain unique value }} - inst = __{{enum:name}}EnumUniqueValues.get(value) - if inst is None: - inst = __{{enum:name}}EnumUniqueValues[value] = {{enum:name}}.__new__({{enum:name}}, value, name) - __{{enum:name}}EnumMembers[name] = inst - return inst -{{/first?}}{{/enum:values}} + def __get_all_names(cls): + return __{{enum:name}}_enum_data.get_all_names() + + def __len__(cls): + return __{{enum:name}}_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class {{enum:name}}(thrift.py3.types.{{^enum:flags?}}CompiledEnum{{/enum:flags?}}{{#enum:flags?}}Flag{{/enum:flags?}}): - {{#enum:values}} - {{enumValue:enumSafeName}} = __{{enum:name}}_unique_instance({{enumValue:value}}, "{{enumValue:enumSafeName}}") - {{/enum:values}} - __members__ = thrift.py3.types.MappingProxyType(__{{enum:name}}EnumMembers) - - def __cinit__(self, value, name): - {{^enum:flags?}} - if __{{enum:name}}EnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - {{/enum:flags?}} - {{#enum:flags?}} - __ExistingValues = __{{enum:name}}EnumValueMapping - cdef int temp - if __ExistingValues is not None: - {{! This is a combination value, not a predefined }} - if value < 0 or value in __ExistingValues: - raise TypeError('__new__ is disabled in the interest of type-safety') - elif value == 0: - name = "0" - else: - {{! Find the decomposed value }} - combo = [] - temp = value - while temp: - flag = thrift.py3.types.largest_flag(temp) - if flag not in __ExistingValues: - raise ValueError(f'{value} is not a valid {{enum:name}}') - combo.append(__ExistingValues[flag].name) - temp ^= flag - name = '|'.join(combo) - {{! Save so combo instances are re-used, this mirrors enum.Flag from python }} - __ExistingValues[value] = self - {{/enum:flags?}} - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"{{enum:name}}.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, {{enum:name}}): - warnings.warn(f"comparison not supported between instances of { {{enum:name}} } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return {{enum:name}}, (self.value,) -{{#enum:flags?}} - - def __contains__(self, other): - if not isinstance(other, {{enum:name}}): - return NotImplemented - return other.value & self.value == other.value - - def __bool__(self): - return bool(self.value) - - def __or__(self, other): - if not isinstance(other, {{enum:name}}): - return NotImplemented - return {{enum:name}}(self.value | other.value) - - def __and__(self, other): - if not isinstance(other, {{enum:name}}): - return NotImplemented - return {{enum:name}}(self.value & other.value) + cdef get_by_name(self, str name): + return __{{enum:name}}_enum_data.get_by_name(name) - def __xor__(self, other): - if not isinstance(other, {{enum:name}}): - return NotImplemented - return {{enum:name}}(self.value ^ other.value) + {{#enum:flags?}} def __invert__(self): - inverted = {{enum:name}}(0) - for m in {{enum:name}}: - if not (m.value & self.value): - inverted = inverted | m - return {{enum:name}}(inverted) -{{/enum:flags?}} + return __{{enum:name}}_enum_data.get_invert(self.value) + {{/enum:flags?}} __SetMetaClass( {{enum:name}}, __{{enum:name}}Meta) -__{{enum:name}}EnumInstances = set(__{{enum:name}}EnumUniqueValues.values()) -{{#enum:flags?}} -__{{enum:name}}EnumValueMapping = __weakref.WeakValueDictionary( - {f.value: f for f in tuple({{enum:name}})} -) -{{/enum:flags?}} - -cdef inline c{{enum:name}} {{enum:name}}_to_cpp({{enum:name}} value): - {{^enum:flags?}} - {{! We do .value once because it slow Python, and Cython will turn the - if/elif chain into a switch statement when the vars on both sides are - C ints - }} - cdef int cvalue = value.value - {{#enum:values}} - {{^first?}}el{{/first?}}if cvalue == {{enumValue:value}}: - return {{enum:name}}__{{enumValue:py_name}}{{! This is from cpp so not enumSafeName }} - {{/enum:values}} - {{^enum:values}} - pass - {{/enum:values}} - {{/enum:flags?}} - {{#enum:flags?}} - return (value.value) - {{/enum:flags?}} {{/program:enums}} diff --git a/thrift/compiler/generate/templates/py3/types/enumDefs.mustache b/thrift/compiler/generate/templates/py3/types/enumDefs.mustache index bb2baa8a608..83d575c3958 100644 --- a/thrift/compiler/generate/templates/py3/types/enumDefs.mustache +++ b/thrift/compiler/generate/templates/py3/types/enumDefs.mustache @@ -24,9 +24,4 @@ This is a template for creating compiled Enum and Flag pxd information cdef class {{enum:name}}(thrift.py3.types.{{^enum:flags?}}CompiledEnum{{/enum:flags?}}{{#enum:flags?}}Flag{{/enum:flags?}}): pass - - -cdef c{{enum:name}} {{enum:name}}_to_cpp({{enum:name}} value) - - {{/program:enums}} diff --git a/thrift/compiler/generate/templates/py3/types/unionTypeEnum.mustache b/thrift/compiler/generate/templates/py3/types/unionTypeEnum.mustache index 1f29d180204..c5fa6c6a30f 100644 --- a/thrift/compiler/generate/templates/py3/types/unionTypeEnum.mustache +++ b/thrift/compiler/generate/templates/py3/types/unionTypeEnum.mustache @@ -19,113 +19,41 @@ This is a template for creating compiled Enum and Flag pyx information }} + {{#program:structs}} {{#struct:union?}} - -cdef object __{{struct:name}}_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __{{struct:name}}_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[c{{struct:name}}](), + __{{struct:name}}Type, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __{{struct:name}}_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __{{struct:name}}_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __{{struct:name}}Type.EMPTY - {{#struct:fields}} - elif cvalue == {{field:key}}: - return __{{struct:name}}Type.{{field:enumSafeName}} - {{/struct:fields}} - - raise ValueError(f'{value} is not a valid {{struct:name}}.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __{{struct:name}}Type.EMPTY - {{#struct:fields}} - elif name == "{{field:py_name}}": - return __{{struct:name}}Type.{{field:enumSafeName}} - {{/struct:fields}} - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - {{#struct:fields}} - '{{field:enumSafeName}}', - {{/struct:fields}} - ] - - @property - def __members__(cls): - return {m.name: m for m in cls} - - def __iter__(cls): - yield __{{struct:name}}Type.EMPTY - {{#struct:fields}} - yield __{{struct:name}}Type.{{field:enumSafeName}} - {{/struct:fields}} - {{^struct:fields}} - return iter(()) - {{/struct:fields}} - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __{{struct:name}}_Union_TypeEnumMembers +cdef class __{{struct:name}}_Union_TypeMeta(thrift.py3.types.EnumMeta): + + def __get_by_name(cls, str name): + return __{{struct:name}}_union_type_enum_data.get_by_name(name) + + def __get_by_value(cls, int value): + return __{{struct:name}}_union_type_enum_data.get_by_value(value) + + def __get_all_names(cls): + return __{{struct:name}}_union_type_enum_data.get_all_names() def __len__(cls): - return {{struct:size}}+1 # For Empty + return __{{struct:name}}_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __{{struct:name}}Type(thrift.py3.types.CompiledEnum): - EMPTY = __{{struct:name}}Type.__new__(__{{struct:name}}Type, 0, "EMPTY") - {{#struct:fields}} - {{field:enumSafeName}} = __{{struct:name}}Type.__new__(__{{struct:name}}Type, {{field:key}}, "{{field:enumSafeName}}") - {{/struct:fields}} - - def __cinit__(self, value, name): - if __{{struct:name}}_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"{{struct:name}}.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __{{struct:name}}Type): - warnings.warn(f"comparison not supported between instances of { __{{struct:name}}Type } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash + cdef get_by_name(self, str name): + return __{{struct:name}}_union_type_enum_data.get_by_name(name) - def __reduce__(self): - return __{{struct:name}}Type, (self.value,) __SetMetaClass( __{{struct:name}}Type, __{{struct:name}}_Union_TypeMeta) -__{{struct:name}}_Union_TypeEnumMembers = set(__{{struct:name}}Type) {{/struct:union?}} {{/program:structs}} diff --git a/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.h b/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.h new file mode 100644 index 00000000000..e2e60f005b1 --- /dev/null +++ b/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.h @@ -0,0 +1,22 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::MyEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + diff --git a/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.pxd index 7af125cf907..2a99ab36bcf 100644 --- a/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.pxd @@ -26,15 +26,14 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef cppclass cMyEnum "::cpp2::MyEnum": - bint operator==(cMyEnum&) - bint operator!=(cMyEnum&) - cMyEnum MyEnum__MyValue1 "::cpp2::MyEnum::MyValue1" - cMyEnum MyEnum__MyValue2 "::cpp2::MyEnum::MyValue2" - cMyEnum MyEnum__DOMAIN "::cpp2::MyEnum::REALM" + pass + @@ -42,11 +41,6 @@ cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef class MyEnum(thrift.py3.types.CompiledEnum): pass - -cdef cMyEnum MyEnum_to_cpp(MyEnum value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::cpp2": cdef cppclass cMyStructNestedAnnotation__isset "::cpp2::MyStructNestedAnnotation::__isset": bint name diff --git a/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.pyx index f81bfbb619d..6aae746253e 100644 --- a/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/basic-annotations/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,118 +37,43 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection -cdef object __MyEnumEnumInstances = None # Set[MyEnum] -cdef object __MyEnumEnumMembers = {} # Dict[str, MyEnum] -cdef object __MyEnumEnumUniqueValues = dict() # Dict[int, MyEnum] + +cdef __EnumData __MyEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cMyEnum](), MyEnum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __MyEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return MyEnum.MyValue1 - elif cvalue == 1: - return MyEnum.MyValue2 - elif cvalue == 2: - return MyEnum.DOMAIN - - raise ValueError(f'{value} is not a valid MyEnum') - - def __getitem__(cls, name): - return __MyEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'MyValue1', - 'MyValue2', - 'DOMAIN', - ] - - def __iter__(cls): - return iter(__MyEnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyEnumEnumInstances +cdef class __MyEnumMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__MyEnumEnumInstances) + def __get_by_name(cls, str name): + return __MyEnum_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __MyEnum_enum_data.get_by_value(value) -cdef __MyEnum_unique_instance(int value, str name): - inst = __MyEnumEnumUniqueValues.get(value) - if inst is None: - inst = __MyEnumEnumUniqueValues[value] = MyEnum.__new__(MyEnum, value, name) - __MyEnumEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __MyEnum_enum_data.get_all_names() + + def __len__(cls): + return __MyEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class MyEnum(thrift.py3.types.CompiledEnum): - MyValue1 = __MyEnum_unique_instance(0, "MyValue1") - MyValue2 = __MyEnum_unique_instance(1, "MyValue2") - DOMAIN = __MyEnum_unique_instance(2, "DOMAIN") - __members__ = thrift.py3.types.MappingProxyType(__MyEnumEnumMembers) - - def __cinit__(self, value, name): - if __MyEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, MyEnum): - warnings.warn(f"comparison not supported between instances of { MyEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash + cdef get_by_name(self, str name): + return __MyEnum_enum_data.get_by_name(name) - def __reduce__(self): - return MyEnum, (self.value,) __SetMetaClass( MyEnum, __MyEnumMeta) -__MyEnumEnumInstances = set(__MyEnumEnumUniqueValues.values()) -cdef inline cMyEnum MyEnum_to_cpp(MyEnum value): - cdef int cvalue = value.value - if cvalue == 0: - return MyEnum__MyValue1 - elif cvalue == 1: - return MyEnum__MyValue2 - elif cvalue == 2: - return MyEnum__DOMAIN @__cython.auto_pickle(False) cdef class MyStructNestedAnnotation(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/basic-enum/gen-py3/module/types.h b/thrift/compiler/test/fixtures/basic-enum/gen-py3/module/types.h new file mode 100644 index 00000000000..81aed1a788c --- /dev/null +++ b/thrift/compiler/test/fixtures/basic-enum/gen-py3/module/types.h @@ -0,0 +1,44 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::test::fixtures::enumstrict::EmptyEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::test::fixtures::enumstrict::MyEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::test::fixtures::enumstrict::MyBigEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + diff --git a/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.h b/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.h new file mode 100644 index 00000000000..81aed1a788c --- /dev/null +++ b/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.h @@ -0,0 +1,44 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::test::fixtures::enumstrict::EmptyEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::test::fixtures::enumstrict::MyEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::test::fixtures::enumstrict::MyBigEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + diff --git a/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.pxd b/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.pxd index df8bebc9220..ddc300dc42b 100644 --- a/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.pxd +++ b/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.pxd @@ -26,40 +26,20 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from "src/gen-cpp2/module_types.h" namespace "::test::fixtures::enumstrict": cdef cppclass cEmptyEnum "::test::fixtures::enumstrict::EmptyEnum": - bint operator==(cEmptyEnum&) - bint operator!=(cEmptyEnum&) + pass + cdef cppclass cMyEnum "::test::fixtures::enumstrict::MyEnum": - bint operator==(cMyEnum&) - bint operator!=(cMyEnum&) - cMyEnum MyEnum__ONE "::test::fixtures::enumstrict::MyEnum::ONE" - cMyEnum MyEnum__TWO "::test::fixtures::enumstrict::MyEnum::TWO" + pass + cdef cppclass cMyBigEnum "::test::fixtures::enumstrict::MyBigEnum": - bint operator==(cMyBigEnum&) - bint operator!=(cMyBigEnum&) - cMyBigEnum MyBigEnum__UNKNOWN "::test::fixtures::enumstrict::MyBigEnum::UNKNOWN" - cMyBigEnum MyBigEnum__ONE "::test::fixtures::enumstrict::MyBigEnum::ONE" - cMyBigEnum MyBigEnum__TWO "::test::fixtures::enumstrict::MyBigEnum::TWO" - cMyBigEnum MyBigEnum__THREE "::test::fixtures::enumstrict::MyBigEnum::THREE" - cMyBigEnum MyBigEnum__FOUR "::test::fixtures::enumstrict::MyBigEnum::FOUR" - cMyBigEnum MyBigEnum__FIVE "::test::fixtures::enumstrict::MyBigEnum::FIVE" - cMyBigEnum MyBigEnum__SIX "::test::fixtures::enumstrict::MyBigEnum::SIX" - cMyBigEnum MyBigEnum__SEVEN "::test::fixtures::enumstrict::MyBigEnum::SEVEN" - cMyBigEnum MyBigEnum__EIGHT "::test::fixtures::enumstrict::MyBigEnum::EIGHT" - cMyBigEnum MyBigEnum__NINE "::test::fixtures::enumstrict::MyBigEnum::NINE" - cMyBigEnum MyBigEnum__TEN "::test::fixtures::enumstrict::MyBigEnum::TEN" - cMyBigEnum MyBigEnum__ELEVEN "::test::fixtures::enumstrict::MyBigEnum::ELEVEN" - cMyBigEnum MyBigEnum__TWELVE "::test::fixtures::enumstrict::MyBigEnum::TWELVE" - cMyBigEnum MyBigEnum__THIRTEEN "::test::fixtures::enumstrict::MyBigEnum::THIRTEEN" - cMyBigEnum MyBigEnum__FOURTEEN "::test::fixtures::enumstrict::MyBigEnum::FOURTEEN" - cMyBigEnum MyBigEnum__FIFTEEN "::test::fixtures::enumstrict::MyBigEnum::FIFTEEN" - cMyBigEnum MyBigEnum__SIXTEEN "::test::fixtures::enumstrict::MyBigEnum::SIXTEEN" - cMyBigEnum MyBigEnum__SEVENTEEN "::test::fixtures::enumstrict::MyBigEnum::SEVENTEEN" - cMyBigEnum MyBigEnum__EIGHTEEN "::test::fixtures::enumstrict::MyBigEnum::EIGHTEEN" - cMyBigEnum MyBigEnum__NINETEEN "::test::fixtures::enumstrict::MyBigEnum::NINETEEN" + pass + @@ -68,28 +48,13 @@ cdef class EmptyEnum(thrift.py3.types.CompiledEnum): pass -cdef cEmptyEnum EmptyEnum_to_cpp(EmptyEnum value) - - - - cdef class MyEnum(thrift.py3.types.CompiledEnum): pass -cdef cMyEnum MyEnum_to_cpp(MyEnum value) - - - - cdef class MyBigEnum(thrift.py3.types.CompiledEnum): pass - -cdef cMyBigEnum MyBigEnum_to_cpp(MyBigEnum value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::test::fixtures::enumstrict": cdef cppclass cMyStruct__isset "::test::fixtures::enumstrict::MyStruct::__isset": bint myEnum diff --git a/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.pyx b/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.pyx index 883993b049e..769d0c4b653 100644 --- a/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.pyx +++ b/thrift/compiler/test/fixtures/basic-enum/gen-py3/test/fixtures/enumstrict/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,403 +37,105 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport test.fixtures.enumstrict.module.types_reflection as _types_reflection -cdef object __EmptyEnumEnumInstances = None # Set[EmptyEnum] -cdef object __EmptyEnumEnumMembers = {} # Dict[str, EmptyEnum] -cdef object __EmptyEnumEnumUniqueValues = dict() # Dict[int, EmptyEnum] -@__cython.internal -@__cython.auto_pickle(False) -cdef class __EmptyEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value +cdef __EnumData __EmptyEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cEmptyEnum](), EmptyEnum) - raise ValueError(f'{value} is not a valid EmptyEnum') - def __getitem__(cls, name): - return __EmptyEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - ] +@__cython.internal +@__cython.auto_pickle(False) +cdef class __EmptyEnumMeta(thrift.py3.types.EnumMeta): - def __iter__(cls): - return iter(__EmptyEnumEnumUniqueValues.values()) + def __get_by_name(cls, str name): + return __EmptyEnum_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __EmptyEnum_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __EmptyEnumEnumInstances + def __get_all_names(cls): + return __EmptyEnum_enum_data.get_all_names() def __len__(cls): - return len(__EmptyEnumEnumInstances) - - + return __EmptyEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class EmptyEnum(thrift.py3.types.CompiledEnum): - __members__ = thrift.py3.types.MappingProxyType(__EmptyEnumEnumMembers) - - def __cinit__(self, value, name): - if __EmptyEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"EmptyEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" + cdef get_by_name(self, str name): + return __EmptyEnum_enum_data.get_by_name(name) - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, EmptyEnum): - warnings.warn(f"comparison not supported between instances of { EmptyEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return EmptyEnum, (self.value,) __SetMetaClass( EmptyEnum, __EmptyEnumMeta) -__EmptyEnumEnumInstances = set(__EmptyEnumEnumUniqueValues.values()) -cdef inline cEmptyEnum EmptyEnum_to_cpp(EmptyEnum value): - cdef int cvalue = value.value - pass -cdef object __MyEnumEnumInstances = None # Set[MyEnum] -cdef object __MyEnumEnumMembers = {} # Dict[str, MyEnum] -cdef object __MyEnumEnumUniqueValues = dict() # Dict[int, MyEnum] +cdef __EnumData __MyEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cMyEnum](), MyEnum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __MyEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 1: - return MyEnum.ONE - elif cvalue == 2: - return MyEnum.TWO - - raise ValueError(f'{value} is not a valid MyEnum') - - def __getitem__(cls, name): - return __MyEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'ONE', - 'TWO', - ] - - def __iter__(cls): - return iter(__MyEnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyEnumEnumInstances +cdef class __MyEnumMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__MyEnumEnumInstances) + def __get_by_name(cls, str name): + return __MyEnum_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __MyEnum_enum_data.get_by_value(value) -cdef __MyEnum_unique_instance(int value, str name): - inst = __MyEnumEnumUniqueValues.get(value) - if inst is None: - inst = __MyEnumEnumUniqueValues[value] = MyEnum.__new__(MyEnum, value, name) - __MyEnumEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __MyEnum_enum_data.get_all_names() + + def __len__(cls): + return __MyEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class MyEnum(thrift.py3.types.CompiledEnum): - ONE = __MyEnum_unique_instance(1, "ONE") - TWO = __MyEnum_unique_instance(2, "TWO") - __members__ = thrift.py3.types.MappingProxyType(__MyEnumEnumMembers) - - def __cinit__(self, value, name): - if __MyEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, MyEnum): - warnings.warn(f"comparison not supported between instances of { MyEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash + cdef get_by_name(self, str name): + return __MyEnum_enum_data.get_by_name(name) - def __reduce__(self): - return MyEnum, (self.value,) __SetMetaClass( MyEnum, __MyEnumMeta) -__MyEnumEnumInstances = set(__MyEnumEnumUniqueValues.values()) -cdef inline cMyEnum MyEnum_to_cpp(MyEnum value): - cdef int cvalue = value.value - if cvalue == 1: - return MyEnum__ONE - elif cvalue == 2: - return MyEnum__TWO -cdef object __MyBigEnumEnumInstances = None # Set[MyBigEnum] -cdef object __MyBigEnumEnumMembers = {} # Dict[str, MyBigEnum] -cdef object __MyBigEnumEnumUniqueValues = dict() # Dict[int, MyBigEnum] +cdef __EnumData __MyBigEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cMyBigEnum](), MyBigEnum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __MyBigEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return MyBigEnum.UNKNOWN - elif cvalue == 1: - return MyBigEnum.ONE - elif cvalue == 2: - return MyBigEnum.TWO - elif cvalue == 3: - return MyBigEnum.THREE - elif cvalue == 4: - return MyBigEnum.FOUR - elif cvalue == 5: - return MyBigEnum.FIVE - elif cvalue == 6: - return MyBigEnum.SIX - elif cvalue == 7: - return MyBigEnum.SEVEN - elif cvalue == 8: - return MyBigEnum.EIGHT - elif cvalue == 9: - return MyBigEnum.NINE - elif cvalue == 10: - return MyBigEnum.TEN - elif cvalue == 11: - return MyBigEnum.ELEVEN - elif cvalue == 12: - return MyBigEnum.TWELVE - elif cvalue == 13: - return MyBigEnum.THIRTEEN - elif cvalue == 14: - return MyBigEnum.FOURTEEN - elif cvalue == 15: - return MyBigEnum.FIFTEEN - elif cvalue == 16: - return MyBigEnum.SIXTEEN - elif cvalue == 17: - return MyBigEnum.SEVENTEEN - elif cvalue == 18: - return MyBigEnum.EIGHTEEN - elif cvalue == 19: - return MyBigEnum.NINETEEN - - raise ValueError(f'{value} is not a valid MyBigEnum') - - def __getitem__(cls, name): - return __MyBigEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'UNKNOWN', - 'ONE', - 'TWO', - 'THREE', - 'FOUR', - 'FIVE', - 'SIX', - 'SEVEN', - 'EIGHT', - 'NINE', - 'TEN', - 'ELEVEN', - 'TWELVE', - 'THIRTEEN', - 'FOURTEEN', - 'FIFTEEN', - 'SIXTEEN', - 'SEVENTEEN', - 'EIGHTEEN', - 'NINETEEN', - ] - - def __iter__(cls): - return iter(__MyBigEnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyBigEnumEnumInstances +cdef class __MyBigEnumMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__MyBigEnumEnumInstances) + def __get_by_name(cls, str name): + return __MyBigEnum_enum_data.get_by_name(name) + + def __get_by_value(cls, int value): + return __MyBigEnum_enum_data.get_by_value(value) + def __get_all_names(cls): + return __MyBigEnum_enum_data.get_all_names() -cdef __MyBigEnum_unique_instance(int value, str name): - inst = __MyBigEnumEnumUniqueValues.get(value) - if inst is None: - inst = __MyBigEnumEnumUniqueValues[value] = MyBigEnum.__new__(MyBigEnum, value, name) - __MyBigEnumEnumMembers[name] = inst - return inst + def __len__(cls): + return __MyBigEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class MyBigEnum(thrift.py3.types.CompiledEnum): - UNKNOWN = __MyBigEnum_unique_instance(0, "UNKNOWN") - ONE = __MyBigEnum_unique_instance(1, "ONE") - TWO = __MyBigEnum_unique_instance(2, "TWO") - THREE = __MyBigEnum_unique_instance(3, "THREE") - FOUR = __MyBigEnum_unique_instance(4, "FOUR") - FIVE = __MyBigEnum_unique_instance(5, "FIVE") - SIX = __MyBigEnum_unique_instance(6, "SIX") - SEVEN = __MyBigEnum_unique_instance(7, "SEVEN") - EIGHT = __MyBigEnum_unique_instance(8, "EIGHT") - NINE = __MyBigEnum_unique_instance(9, "NINE") - TEN = __MyBigEnum_unique_instance(10, "TEN") - ELEVEN = __MyBigEnum_unique_instance(11, "ELEVEN") - TWELVE = __MyBigEnum_unique_instance(12, "TWELVE") - THIRTEEN = __MyBigEnum_unique_instance(13, "THIRTEEN") - FOURTEEN = __MyBigEnum_unique_instance(14, "FOURTEEN") - FIFTEEN = __MyBigEnum_unique_instance(15, "FIFTEEN") - SIXTEEN = __MyBigEnum_unique_instance(16, "SIXTEEN") - SEVENTEEN = __MyBigEnum_unique_instance(17, "SEVENTEEN") - EIGHTEEN = __MyBigEnum_unique_instance(18, "EIGHTEEN") - NINETEEN = __MyBigEnum_unique_instance(19, "NINETEEN") - __members__ = thrift.py3.types.MappingProxyType(__MyBigEnumEnumMembers) - - def __cinit__(self, value, name): - if __MyBigEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyBigEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, MyBigEnum): - warnings.warn(f"comparison not supported between instances of { MyBigEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash + cdef get_by_name(self, str name): + return __MyBigEnum_enum_data.get_by_name(name) - def __reduce__(self): - return MyBigEnum, (self.value,) __SetMetaClass( MyBigEnum, __MyBigEnumMeta) -__MyBigEnumEnumInstances = set(__MyBigEnumEnumUniqueValues.values()) - - -cdef inline cMyBigEnum MyBigEnum_to_cpp(MyBigEnum value): - cdef int cvalue = value.value - if cvalue == 0: - return MyBigEnum__UNKNOWN - elif cvalue == 1: - return MyBigEnum__ONE - elif cvalue == 2: - return MyBigEnum__TWO - elif cvalue == 3: - return MyBigEnum__THREE - elif cvalue == 4: - return MyBigEnum__FOUR - elif cvalue == 5: - return MyBigEnum__FIVE - elif cvalue == 6: - return MyBigEnum__SIX - elif cvalue == 7: - return MyBigEnum__SEVEN - elif cvalue == 8: - return MyBigEnum__EIGHT - elif cvalue == 9: - return MyBigEnum__NINE - elif cvalue == 10: - return MyBigEnum__TEN - elif cvalue == 11: - return MyBigEnum__ELEVEN - elif cvalue == 12: - return MyBigEnum__TWELVE - elif cvalue == 13: - return MyBigEnum__THIRTEEN - elif cvalue == 14: - return MyBigEnum__FOURTEEN - elif cvalue == 15: - return MyBigEnum__FIFTEEN - elif cvalue == 16: - return MyBigEnum__SIXTEEN - elif cvalue == 17: - return MyBigEnum__SEVENTEEN - elif cvalue == 18: - return MyBigEnum__EIGHTEEN - elif cvalue == 19: - return MyBigEnum__NINETEEN + + @__cython.auto_pickle(False) cdef class MyStruct(thrift.py3.types.Struct): @@ -515,10 +222,10 @@ cdef class MyStruct(thrift.py3.types.Struct): pass if myEnum is not None: - deref(c_inst).myEnum_ref().assign(MyEnum_to_cpp(myEnum)) + deref(c_inst).myEnum_ref().assign(myEnum) deref(c_inst).__isset.myEnum = True if myBigEnum is not None: - deref(c_inst).myBigEnum_ref().assign(MyBigEnum_to_cpp(myBigEnum)) + deref(c_inst).myBigEnum_ref().assign(myBigEnum) deref(c_inst).__isset.myBigEnum = True # in C++ you don't have to call move(), but this doesn't translate # into a C++ return statement, so you do here diff --git a/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.h b/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.h new file mode 100644 index 00000000000..e2e60f005b1 --- /dev/null +++ b/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.h @@ -0,0 +1,22 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::MyEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + diff --git a/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.pxd index ef7cc16b819..5da04fa087e 100644 --- a/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.pxd @@ -26,14 +26,14 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef cppclass cMyEnum "::cpp2::MyEnum": - bint operator==(cMyEnum&) - bint operator!=(cMyEnum&) - cMyEnum MyEnum__MyValue1 "::cpp2::MyEnum::MyValue1" - cMyEnum MyEnum__MyValue2 "::cpp2::MyEnum::MyValue2" + pass + @@ -41,11 +41,6 @@ cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef class MyEnum(thrift.py3.types.CompiledEnum): pass - -cdef cMyEnum MyEnum_to_cpp(MyEnum value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::cpp2": cdef cppclass cMyStruct__isset "::cpp2::MyStruct::__isset": bint MyIntField diff --git a/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.pyx index 5774671844e..8f6c4695d4c 100644 --- a/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/basic-stack-arguments/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,112 +37,43 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection -cdef object __MyEnumEnumInstances = None # Set[MyEnum] -cdef object __MyEnumEnumMembers = {} # Dict[str, MyEnum] -cdef object __MyEnumEnumUniqueValues = dict() # Dict[int, MyEnum] + +cdef __EnumData __MyEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cMyEnum](), MyEnum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __MyEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return MyEnum.MyValue1 - elif cvalue == 1: - return MyEnum.MyValue2 - - raise ValueError(f'{value} is not a valid MyEnum') - - def __getitem__(cls, name): - return __MyEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'MyValue1', - 'MyValue2', - ] - - def __iter__(cls): - return iter(__MyEnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyEnumEnumInstances +cdef class __MyEnumMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__MyEnumEnumInstances) + def __get_by_name(cls, str name): + return __MyEnum_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __MyEnum_enum_data.get_by_value(value) -cdef __MyEnum_unique_instance(int value, str name): - inst = __MyEnumEnumUniqueValues.get(value) - if inst is None: - inst = __MyEnumEnumUniqueValues[value] = MyEnum.__new__(MyEnum, value, name) - __MyEnumEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __MyEnum_enum_data.get_all_names() + + def __len__(cls): + return __MyEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class MyEnum(thrift.py3.types.CompiledEnum): - MyValue1 = __MyEnum_unique_instance(0, "MyValue1") - MyValue2 = __MyEnum_unique_instance(1, "MyValue2") - __members__ = thrift.py3.types.MappingProxyType(__MyEnumEnumMembers) - - def __cinit__(self, value, name): - if __MyEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, MyEnum): - warnings.warn(f"comparison not supported between instances of { MyEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash + cdef get_by_name(self, str name): + return __MyEnum_enum_data.get_by_name(name) - def __reduce__(self): - return MyEnum, (self.value,) __SetMetaClass( MyEnum, __MyEnumMeta) -__MyEnumEnumInstances = set(__MyEnumEnumUniqueValues.values()) -cdef inline cMyEnum MyEnum_to_cpp(MyEnum value): - cdef int cvalue = value.value - if cvalue == 0: - return MyEnum__MyValue1 - elif cvalue == 1: - return MyEnum__MyValue2 @__cython.auto_pickle(False) cdef class MyStruct(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/basic/gen-py3/module/types.h b/thrift/compiler/test/fixtures/basic/gen-py3/module/types.h new file mode 100644 index 00000000000..287ba1446f0 --- /dev/null +++ b/thrift/compiler/test/fixtures/basic/gen-py3/module/types.h @@ -0,0 +1,32 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::MyEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::MyUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} diff --git a/thrift/compiler/test/fixtures/basic/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/basic/gen-py3/module/types.pxd index 9a59689f330..93df9a40e6c 100644 --- a/thrift/compiler/test/fixtures/basic/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/basic/gen-py3/module/types.pxd @@ -26,14 +26,14 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef cppclass cMyEnum "::cpp2::MyEnum": - bint operator==(cMyEnum&) - bint operator!=(cMyEnum&) - cMyEnum MyEnum__MyValue1 "::cpp2::MyEnum::MyValue1" - cMyEnum MyEnum__MyValue2 "::cpp2::MyEnum::MyValue2" + pass + @@ -41,11 +41,6 @@ cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef class MyEnum(thrift.py3.types.CompiledEnum): pass - -cdef cMyEnum MyEnum_to_cpp(MyEnum value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::cpp2": cdef cppclass cMyStruct__isset "::cpp2::MyStruct::__isset": bint MyIntField diff --git a/thrift/compiler/test/fixtures/basic/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/basic/gen-py3/module/types.pyx index f4ba1547805..05351482e67 100644 --- a/thrift/compiler/test/fixtures/basic/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/basic/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,218 +37,75 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection -cdef object __MyEnumEnumInstances = None # Set[MyEnum] -cdef object __MyEnumEnumMembers = {} # Dict[str, MyEnum] -cdef object __MyEnumEnumUniqueValues = dict() # Dict[int, MyEnum] + +cdef __EnumData __MyEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cMyEnum](), MyEnum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __MyEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return MyEnum.MyValue1 - elif cvalue == 1: - return MyEnum.MyValue2 - - raise ValueError(f'{value} is not a valid MyEnum') - - def __getitem__(cls, name): - return __MyEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'MyValue1', - 'MyValue2', - ] - - def __iter__(cls): - return iter(__MyEnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyEnumEnumInstances +cdef class __MyEnumMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__MyEnumEnumInstances) + def __get_by_name(cls, str name): + return __MyEnum_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __MyEnum_enum_data.get_by_value(value) -cdef __MyEnum_unique_instance(int value, str name): - inst = __MyEnumEnumUniqueValues.get(value) - if inst is None: - inst = __MyEnumEnumUniqueValues[value] = MyEnum.__new__(MyEnum, value, name) - __MyEnumEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __MyEnum_enum_data.get_all_names() + + def __len__(cls): + return __MyEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class MyEnum(thrift.py3.types.CompiledEnum): - MyValue1 = __MyEnum_unique_instance(0, "MyValue1") - MyValue2 = __MyEnum_unique_instance(1, "MyValue2") - __members__ = thrift.py3.types.MappingProxyType(__MyEnumEnumMembers) - - def __cinit__(self, value, name): - if __MyEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, MyEnum): - warnings.warn(f"comparison not supported between instances of { MyEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other + cdef get_by_name(self, str name): + return __MyEnum_enum_data.get_by_name(name) - def __hash__(self): - return self.__hash - - def __reduce__(self): - return MyEnum, (self.value,) __SetMetaClass( MyEnum, __MyEnumMeta) -__MyEnumEnumInstances = set(__MyEnumEnumUniqueValues.values()) -cdef inline cMyEnum MyEnum_to_cpp(MyEnum value): - cdef int cvalue = value.value - if cvalue == 0: - return MyEnum__MyValue1 - elif cvalue == 1: - return MyEnum__MyValue2 - -cdef object __MyUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __MyUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cMyUnion](), + __MyUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __MyUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __MyUnion_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __MyUnionType.EMPTY - elif cvalue == 1: - return __MyUnionType.myEnum - elif cvalue == 2: - return __MyUnionType.myStruct - elif cvalue == 3: - return __MyUnionType.myDataItem - - raise ValueError(f'{value} is not a valid MyUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __MyUnionType.EMPTY - elif name == "myEnum": - return __MyUnionType.myEnum - elif name == "myStruct": - return __MyUnionType.myStruct - elif name == "myDataItem": - return __MyUnionType.myDataItem - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'myEnum', - 'myStruct', - 'myDataItem', - ] +cdef class __MyUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - @property - def __members__(cls): - return {m.name: m for m in cls} + def __get_by_name(cls, str name): + return __MyUnion_union_type_enum_data.get_by_name(name) - def __iter__(cls): - yield __MyUnionType.EMPTY - yield __MyUnionType.myEnum - yield __MyUnionType.myStruct - yield __MyUnionType.myDataItem + def __get_by_value(cls, int value): + return __MyUnion_union_type_enum_data.get_by_value(value) - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __MyUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 3+1 # For Empty + return __MyUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __MyUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __MyUnionType.__new__(__MyUnionType, 0, "EMPTY") - myEnum = __MyUnionType.__new__(__MyUnionType, 1, "myEnum") - myStruct = __MyUnionType.__new__(__MyUnionType, 2, "myStruct") - myDataItem = __MyUnionType.__new__(__MyUnionType, 3, "myDataItem") - - def __cinit__(self, value, name): - if __MyUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value + cdef get_by_name(self, str name): + return __MyUnion_union_type_enum_data.get_by_name(name) - def __eq__(self, other): - if not isinstance(other, __MyUnionType): - warnings.warn(f"comparison not supported between instances of { __MyUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __MyUnionType, (self.value,) __SetMetaClass( __MyUnionType, __MyUnion_Union_TypeMeta) -__MyUnion_Union_TypeEnumMembers = set(__MyUnionType) @__cython.auto_pickle(False) @@ -388,7 +250,7 @@ cdef class MyStruct(thrift.py3.types.Struct): deref(c_inst).MyDataField_ref().assign(deref(( MyDataField)._cpp_obj)) deref(c_inst).__isset.MyDataField = True if myEnum is not None: - deref(c_inst).myEnum_ref().assign(MyEnum_to_cpp(myEnum)) + deref(c_inst).myEnum_ref().assign(myEnum) deref(c_inst).__isset.myEnum = True # in C++ you don't have to call move(), but this doesn't translate # into a C++ return statement, so you do here @@ -714,7 +576,7 @@ cdef class MyUnion(thrift.py3.types.Union): if myEnum is not None: if any_set: raise TypeError("At most one field may be set when initializing a union") - deref(c_inst).set_myEnum(MyEnum_to_cpp(myEnum)) + deref(c_inst).set_myEnum(myEnum) any_set = True if myStruct is not None: if any_set: diff --git a/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.h b/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.h new file mode 100644 index 00000000000..41c76da429f --- /dev/null +++ b/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.h @@ -0,0 +1,71 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::ComplexUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::ListUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::DataUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::ValUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::VirtualComplexUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::NonCopyableUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} diff --git a/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.pxd index cc94e8642fb..92b621e7f1f 100644 --- a/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.pyx index 952144fe3a6..60ff816aa30 100644 --- a/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/complex-union/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins @@ -40,624 +44,202 @@ cimport module.types_reflection as _types_reflection -cdef object __ComplexUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __ComplexUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cComplexUnion](), + __ComplexUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __ComplexUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __ComplexUnion_Union_TypeEnumMembers: - return value +cdef class __ComplexUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __ComplexUnionType.EMPTY - elif cvalue == 1: - return __ComplexUnionType.intValue - elif cvalue == 5: - return __ComplexUnionType.stringValue - elif cvalue == 2: - return __ComplexUnionType.intListValue - elif cvalue == 3: - return __ComplexUnionType.stringListValue - elif cvalue == 9: - return __ComplexUnionType.typedefValue - elif cvalue == 14: - return __ComplexUnionType.stringRef - - raise ValueError(f'{value} is not a valid ComplexUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __ComplexUnionType.EMPTY - elif name == "intValue": - return __ComplexUnionType.intValue - elif name == "stringValue": - return __ComplexUnionType.stringValue - elif name == "intListValue": - return __ComplexUnionType.intListValue - elif name == "stringListValue": - return __ComplexUnionType.stringListValue - elif name == "typedefValue": - return __ComplexUnionType.typedefValue - elif name == "stringRef": - return __ComplexUnionType.stringRef - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'intValue', - 'stringValue', - 'intListValue', - 'stringListValue', - 'typedefValue', - 'stringRef', - ] + def __get_by_name(cls, str name): + return __ComplexUnion_union_type_enum_data.get_by_name(name) - @property - def __members__(cls): - return {m.name: m for m in cls} - - def __iter__(cls): - yield __ComplexUnionType.EMPTY - yield __ComplexUnionType.intValue - yield __ComplexUnionType.stringValue - yield __ComplexUnionType.intListValue - yield __ComplexUnionType.stringListValue - yield __ComplexUnionType.typedefValue - yield __ComplexUnionType.stringRef - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __ComplexUnion_Union_TypeEnumMembers + def __get_by_value(cls, int value): + return __ComplexUnion_union_type_enum_data.get_by_value(value) + + def __get_all_names(cls): + return __ComplexUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 6+1 # For Empty + return __ComplexUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __ComplexUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __ComplexUnionType.__new__(__ComplexUnionType, 0, "EMPTY") - intValue = __ComplexUnionType.__new__(__ComplexUnionType, 1, "intValue") - stringValue = __ComplexUnionType.__new__(__ComplexUnionType, 5, "stringValue") - intListValue = __ComplexUnionType.__new__(__ComplexUnionType, 2, "intListValue") - stringListValue = __ComplexUnionType.__new__(__ComplexUnionType, 3, "stringListValue") - typedefValue = __ComplexUnionType.__new__(__ComplexUnionType, 9, "typedefValue") - stringRef = __ComplexUnionType.__new__(__ComplexUnionType, 14, "stringRef") - - def __cinit__(self, value, name): - if __ComplexUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"ComplexUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __ComplexUnionType): - warnings.warn(f"comparison not supported between instances of { __ComplexUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash + cdef get_by_name(self, str name): + return __ComplexUnion_union_type_enum_data.get_by_name(name) - def __reduce__(self): - return __ComplexUnionType, (self.value,) __SetMetaClass( __ComplexUnionType, __ComplexUnion_Union_TypeMeta) -__ComplexUnion_Union_TypeEnumMembers = set(__ComplexUnionType) - -cdef object __ListUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __ListUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cListUnion](), + __ListUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __ListUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __ListUnion_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __ListUnionType.EMPTY - elif cvalue == 2: - return __ListUnionType.intListValue - elif cvalue == 3: - return __ListUnionType.stringListValue - - raise ValueError(f'{value} is not a valid ListUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __ListUnionType.EMPTY - elif name == "intListValue": - return __ListUnionType.intListValue - elif name == "stringListValue": - return __ListUnionType.stringListValue - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'intListValue', - 'stringListValue', - ] +cdef class __ListUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - @property - def __members__(cls): - return {m.name: m for m in cls} - - def __iter__(cls): - yield __ListUnionType.EMPTY - yield __ListUnionType.intListValue - yield __ListUnionType.stringListValue + def __get_by_name(cls, str name): + return __ListUnion_union_type_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __ListUnion_union_type_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __ListUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __ListUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 2+1 # For Empty + return __ListUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __ListUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __ListUnionType.__new__(__ListUnionType, 0, "EMPTY") - intListValue = __ListUnionType.__new__(__ListUnionType, 2, "intListValue") - stringListValue = __ListUnionType.__new__(__ListUnionType, 3, "stringListValue") - - def __cinit__(self, value, name): - if __ListUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"ListUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __ListUnionType): - warnings.warn(f"comparison not supported between instances of { __ListUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash + cdef get_by_name(self, str name): + return __ListUnion_union_type_enum_data.get_by_name(name) - def __reduce__(self): - return __ListUnionType, (self.value,) __SetMetaClass( __ListUnionType, __ListUnion_Union_TypeMeta) -__ListUnion_Union_TypeEnumMembers = set(__ListUnionType) - -cdef object __DataUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __DataUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cDataUnion](), + __DataUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __DataUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __DataUnion_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __DataUnionType.EMPTY - elif cvalue == 1: - return __DataUnionType.binaryData - elif cvalue == 2: - return __DataUnionType.stringData - - raise ValueError(f'{value} is not a valid DataUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __DataUnionType.EMPTY - elif name == "binaryData": - return __DataUnionType.binaryData - elif name == "stringData": - return __DataUnionType.stringData - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'binaryData', - 'stringData', - ] - - @property - def __members__(cls): - return {m.name: m for m in cls} +cdef class __DataUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - def __iter__(cls): - yield __DataUnionType.EMPTY - yield __DataUnionType.binaryData - yield __DataUnionType.stringData + def __get_by_name(cls, str name): + return __DataUnion_union_type_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __DataUnion_union_type_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __DataUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __DataUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 2+1 # For Empty + return __DataUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __DataUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __DataUnionType.__new__(__DataUnionType, 0, "EMPTY") - binaryData = __DataUnionType.__new__(__DataUnionType, 1, "binaryData") - stringData = __DataUnionType.__new__(__DataUnionType, 2, "stringData") - - def __cinit__(self, value, name): - if __DataUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"DataUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __DataUnionType): - warnings.warn(f"comparison not supported between instances of { __DataUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other + cdef get_by_name(self, str name): + return __DataUnion_union_type_enum_data.get_by_name(name) - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __DataUnionType, (self.value,) __SetMetaClass( __DataUnionType, __DataUnion_Union_TypeMeta) -__DataUnion_Union_TypeEnumMembers = set(__DataUnionType) - -cdef object __ValUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __ValUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cValUnion](), + __ValUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __ValUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __ValUnion_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __ValUnionType.EMPTY - elif cvalue == 1: - return __ValUnionType.v1 - elif cvalue == 2: - return __ValUnionType.v2 - - raise ValueError(f'{value} is not a valid ValUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __ValUnionType.EMPTY - elif name == "v1": - return __ValUnionType.v1 - elif name == "v2": - return __ValUnionType.v2 - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'v1', - 'v2', - ] +cdef class __ValUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - @property - def __members__(cls): - return {m.name: m for m in cls} + def __get_by_name(cls, str name): + return __ValUnion_union_type_enum_data.get_by_name(name) - def __iter__(cls): - yield __ValUnionType.EMPTY - yield __ValUnionType.v1 - yield __ValUnionType.v2 + def __get_by_value(cls, int value): + return __ValUnion_union_type_enum_data.get_by_value(value) - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __ValUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __ValUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 2+1 # For Empty + return __ValUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __ValUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __ValUnionType.__new__(__ValUnionType, 0, "EMPTY") - v1 = __ValUnionType.__new__(__ValUnionType, 1, "v1") - v2 = __ValUnionType.__new__(__ValUnionType, 2, "v2") - - def __cinit__(self, value, name): - if __ValUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"ValUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __ValUnionType): - warnings.warn(f"comparison not supported between instances of { __ValUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other + cdef get_by_name(self, str name): + return __ValUnion_union_type_enum_data.get_by_name(name) - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __ValUnionType, (self.value,) __SetMetaClass( __ValUnionType, __ValUnion_Union_TypeMeta) -__ValUnion_Union_TypeEnumMembers = set(__ValUnionType) - -cdef object __VirtualComplexUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __VirtualComplexUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cVirtualComplexUnion](), + __VirtualComplexUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __VirtualComplexUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __VirtualComplexUnion_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __VirtualComplexUnionType.EMPTY - elif cvalue == 1: - return __VirtualComplexUnionType.thingOne - elif cvalue == 2: - return __VirtualComplexUnionType.thingTwo - - raise ValueError(f'{value} is not a valid VirtualComplexUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __VirtualComplexUnionType.EMPTY - elif name == "thingOne": - return __VirtualComplexUnionType.thingOne - elif name == "thingTwo": - return __VirtualComplexUnionType.thingTwo - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'thingOne', - 'thingTwo', - ] - - @property - def __members__(cls): - return {m.name: m for m in cls} +cdef class __VirtualComplexUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - def __iter__(cls): - yield __VirtualComplexUnionType.EMPTY - yield __VirtualComplexUnionType.thingOne - yield __VirtualComplexUnionType.thingTwo + def __get_by_name(cls, str name): + return __VirtualComplexUnion_union_type_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __VirtualComplexUnion_union_type_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __VirtualComplexUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __VirtualComplexUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 2+1 # For Empty + return __VirtualComplexUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __VirtualComplexUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __VirtualComplexUnionType.__new__(__VirtualComplexUnionType, 0, "EMPTY") - thingOne = __VirtualComplexUnionType.__new__(__VirtualComplexUnionType, 1, "thingOne") - thingTwo = __VirtualComplexUnionType.__new__(__VirtualComplexUnionType, 2, "thingTwo") - - def __cinit__(self, value, name): - if __VirtualComplexUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"VirtualComplexUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str + cdef get_by_name(self, str name): + return __VirtualComplexUnion_union_type_enum_data.get_by_name(name) - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __VirtualComplexUnionType): - warnings.warn(f"comparison not supported between instances of { __VirtualComplexUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __VirtualComplexUnionType, (self.value,) __SetMetaClass( __VirtualComplexUnionType, __VirtualComplexUnion_Union_TypeMeta) -__VirtualComplexUnion_Union_TypeEnumMembers = set(__VirtualComplexUnionType) - -cdef object __NonCopyableUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __NonCopyableUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cNonCopyableUnion](), + __NonCopyableUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __NonCopyableUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __NonCopyableUnion_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __NonCopyableUnionType.EMPTY - elif cvalue == 1: - return __NonCopyableUnionType.s - - raise ValueError(f'{value} is not a valid NonCopyableUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __NonCopyableUnionType.EMPTY - elif name == "s": - return __NonCopyableUnionType.s - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 's', - ] - - @property - def __members__(cls): - return {m.name: m for m in cls} +cdef class __NonCopyableUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - def __iter__(cls): - yield __NonCopyableUnionType.EMPTY - yield __NonCopyableUnionType.s + def __get_by_name(cls, str name): + return __NonCopyableUnion_union_type_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __NonCopyableUnion_union_type_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __NonCopyableUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __NonCopyableUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 1+1 # For Empty + return __NonCopyableUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __NonCopyableUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __NonCopyableUnionType.__new__(__NonCopyableUnionType, 0, "EMPTY") - s = __NonCopyableUnionType.__new__(__NonCopyableUnionType, 1, "s") - - def __cinit__(self, value, name): - if __NonCopyableUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"NonCopyableUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value + cdef get_by_name(self, str name): + return __NonCopyableUnion_union_type_enum_data.get_by_name(name) - def __eq__(self, other): - if not isinstance(other, __NonCopyableUnionType): - warnings.warn(f"comparison not supported between instances of { __NonCopyableUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __NonCopyableUnionType, (self.value,) __SetMetaClass( __NonCopyableUnionType, __NonCopyableUnion_Union_TypeMeta) -__NonCopyableUnion_Union_TypeEnumMembers = set(__NonCopyableUnionType) diff --git a/thrift/compiler/test/fixtures/constants/gen-py3/module/types.h b/thrift/compiler/test/fixtures/constants/gen-py3/module/types.h new file mode 100644 index 00000000000..af4c67e497f --- /dev/null +++ b/thrift/compiler/test/fixtures/constants/gen-py3/module/types.h @@ -0,0 +1,64 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::EmptyEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::City>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::Company>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::union1::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::union2::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} diff --git a/thrift/compiler/test/fixtures/constants/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/constants/gen-py3/module/types.pxd index 900b177fb02..b4b3cd9c2f7 100644 --- a/thrift/compiler/test/fixtures/constants/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/constants/gen-py3/module/types.pxd @@ -26,26 +26,20 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef cppclass cEmptyEnum "::cpp2::EmptyEnum": - bint operator==(cEmptyEnum&) - bint operator!=(cEmptyEnum&) + pass + cdef cppclass cCity "::cpp2::City": - bint operator==(cCity&) - bint operator!=(cCity&) - cCity City__NYC "::cpp2::City::NYC" - cCity City__MPK "::cpp2::City::MPK" - cCity City__SEA "::cpp2::City::SEA" - cCity City__LON "::cpp2::City::LON" + pass + cdef cppclass cCompany "::cpp2::Company": - bint operator==(cCompany&) - bint operator!=(cCompany&) - cCompany Company__FACEBOOK "::cpp2::Company::FACEBOOK" - cCompany Company__WHATSAPP "::cpp2::Company::WHATSAPP" - cCompany Company__OCULUS "::cpp2::Company::OCULUS" - cCompany Company__INSTAGRAM "::cpp2::Company::INSTAGRAM" + pass + @@ -54,28 +48,13 @@ cdef class EmptyEnum(thrift.py3.types.CompiledEnum): pass -cdef cEmptyEnum EmptyEnum_to_cpp(EmptyEnum value) - - - - cdef class City(thrift.py3.types.CompiledEnum): pass -cdef cCity City_to_cpp(City value) - - - - cdef class Company(thrift.py3.types.CompiledEnum): pass - -cdef cCompany Company_to_cpp(Company value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::cpp2": cdef cppclass cInternship__isset "::cpp2::Internship::__isset": bint weeks diff --git a/thrift/compiler/test/fixtures/constants/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/constants/gen-py3/module/types.pyx index 54a83c6a2ca..3903a0f029c 100644 --- a/thrift/compiler/test/fixtures/constants/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/constants/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,532 +37,170 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection -cdef object __EmptyEnumEnumInstances = None # Set[EmptyEnum] -cdef object __EmptyEnumEnumMembers = {} # Dict[str, EmptyEnum] -cdef object __EmptyEnumEnumUniqueValues = dict() # Dict[int, EmptyEnum] -@__cython.internal -@__cython.auto_pickle(False) -cdef class __EmptyEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value +cdef __EnumData __EmptyEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cEmptyEnum](), EmptyEnum) - raise ValueError(f'{value} is not a valid EmptyEnum') - def __getitem__(cls, name): - return __EmptyEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - ] +@__cython.internal +@__cython.auto_pickle(False) +cdef class __EmptyEnumMeta(thrift.py3.types.EnumMeta): - def __iter__(cls): - return iter(__EmptyEnumEnumUniqueValues.values()) + def __get_by_name(cls, str name): + return __EmptyEnum_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __EmptyEnum_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __EmptyEnumEnumInstances + def __get_all_names(cls): + return __EmptyEnum_enum_data.get_all_names() def __len__(cls): - return len(__EmptyEnumEnumInstances) - - + return __EmptyEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class EmptyEnum(thrift.py3.types.CompiledEnum): - __members__ = thrift.py3.types.MappingProxyType(__EmptyEnumEnumMembers) - - def __cinit__(self, value, name): - if __EmptyEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"EmptyEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr + cdef get_by_name(self, str name): + return __EmptyEnum_enum_data.get_by_name(name) - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, EmptyEnum): - warnings.warn(f"comparison not supported between instances of { EmptyEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return EmptyEnum, (self.value,) __SetMetaClass( EmptyEnum, __EmptyEnumMeta) -__EmptyEnumEnumInstances = set(__EmptyEnumEnumUniqueValues.values()) -cdef inline cEmptyEnum EmptyEnum_to_cpp(EmptyEnum value): - cdef int cvalue = value.value - pass -cdef object __CityEnumInstances = None # Set[City] -cdef object __CityEnumMembers = {} # Dict[str, City] -cdef object __CityEnumUniqueValues = dict() # Dict[int, City] +cdef __EnumData __City_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cCity](), City) + @__cython.internal @__cython.auto_pickle(False) -cdef class __CityMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return City.NYC - elif cvalue == 1: - return City.MPK - elif cvalue == 2: - return City.SEA - elif cvalue == 3: - return City.LON - - raise ValueError(f'{value} is not a valid City') - - def __getitem__(cls, name): - return __CityEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'NYC', - 'MPK', - 'SEA', - 'LON', - ] - - def __iter__(cls): - return iter(__CityEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __CityEnumInstances +cdef class __CityMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__CityEnumInstances) + def __get_by_name(cls, str name): + return __City_enum_data.get_by_name(name) + + def __get_by_value(cls, int value): + return __City_enum_data.get_by_value(value) + def __get_all_names(cls): + return __City_enum_data.get_all_names() -cdef __City_unique_instance(int value, str name): - inst = __CityEnumUniqueValues.get(value) - if inst is None: - inst = __CityEnumUniqueValues[value] = City.__new__(City, value, name) - __CityEnumMembers[name] = inst - return inst + def __len__(cls): + return __City_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class City(thrift.py3.types.CompiledEnum): - NYC = __City_unique_instance(0, "NYC") - MPK = __City_unique_instance(1, "MPK") - SEA = __City_unique_instance(2, "SEA") - LON = __City_unique_instance(3, "LON") - __members__ = thrift.py3.types.MappingProxyType(__CityEnumMembers) - - def __cinit__(self, value, name): - if __CityEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"City.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr + cdef get_by_name(self, str name): + return __City_enum_data.get_by_name(name) - def __str__(self): - return self.__str - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, City): - warnings.warn(f"comparison not supported between instances of { City } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - def __hash__(self): - return self.__hash +__SetMetaClass( City, __CityMeta) - def __reduce__(self): - return City, (self.value,) +cdef __EnumData __Company_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cCompany](), Company) -__SetMetaClass( City, __CityMeta) -__CityEnumInstances = set(__CityEnumUniqueValues.values()) - - -cdef inline cCity City_to_cpp(City value): - cdef int cvalue = value.value - if cvalue == 0: - return City__NYC - elif cvalue == 1: - return City__MPK - elif cvalue == 2: - return City__SEA - elif cvalue == 3: - return City__LON -cdef object __CompanyEnumInstances = None # Set[Company] -cdef object __CompanyEnumMembers = {} # Dict[str, Company] -cdef object __CompanyEnumUniqueValues = dict() # Dict[int, Company] @__cython.internal @__cython.auto_pickle(False) -cdef class __CompanyMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return Company.FACEBOOK - elif cvalue == 1: - return Company.WHATSAPP - elif cvalue == 2: - return Company.OCULUS - elif cvalue == 3: - return Company.INSTAGRAM - - raise ValueError(f'{value} is not a valid Company') - - def __getitem__(cls, name): - return __CompanyEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'FACEBOOK', - 'WHATSAPP', - 'OCULUS', - 'INSTAGRAM', - ] - - def __iter__(cls): - return iter(__CompanyEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __CompanyEnumInstances +cdef class __CompanyMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__CompanyEnumInstances) + def __get_by_name(cls, str name): + return __Company_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __Company_enum_data.get_by_value(value) -cdef __Company_unique_instance(int value, str name): - inst = __CompanyEnumUniqueValues.get(value) - if inst is None: - inst = __CompanyEnumUniqueValues[value] = Company.__new__(Company, value, name) - __CompanyEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __Company_enum_data.get_all_names() + + def __len__(cls): + return __Company_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class Company(thrift.py3.types.CompiledEnum): - FACEBOOK = __Company_unique_instance(0, "FACEBOOK") - WHATSAPP = __Company_unique_instance(1, "WHATSAPP") - OCULUS = __Company_unique_instance(2, "OCULUS") - INSTAGRAM = __Company_unique_instance(3, "INSTAGRAM") - __members__ = thrift.py3.types.MappingProxyType(__CompanyEnumMembers) - - def __cinit__(self, value, name): - if __CompanyEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"Company.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str + cdef get_by_name(self, str name): + return __Company_enum_data.get_by_name(name) - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, Company): - warnings.warn(f"comparison not supported between instances of { Company } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return Company, (self.value,) __SetMetaClass( Company, __CompanyMeta) -__CompanyEnumInstances = set(__CompanyEnumUniqueValues.values()) -cdef inline cCompany Company_to_cpp(Company value): - cdef int cvalue = value.value - if cvalue == 0: - return Company__FACEBOOK - elif cvalue == 1: - return Company__WHATSAPP - elif cvalue == 2: - return Company__OCULUS - elif cvalue == 3: - return Company__INSTAGRAM - -cdef object __union1_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __union1_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cunion1](), + __union1Type, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __union1_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __union1_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __union1Type.EMPTY - elif cvalue == 1: - return __union1Type.i - elif cvalue == 2: - return __union1Type.d - - raise ValueError(f'{value} is not a valid union1.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __union1Type.EMPTY - elif name == "i": - return __union1Type.i - elif name == "d": - return __union1Type.d - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'i', - 'd', - ] - - @property - def __members__(cls): - return {m.name: m for m in cls} +cdef class __union1_Union_TypeMeta(thrift.py3.types.EnumMeta): - def __iter__(cls): - yield __union1Type.EMPTY - yield __union1Type.i - yield __union1Type.d + def __get_by_name(cls, str name): + return __union1_union_type_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __union1_union_type_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __union1_Union_TypeEnumMembers + def __get_all_names(cls): + return __union1_union_type_enum_data.get_all_names() def __len__(cls): - return 2+1 # For Empty + return __union1_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __union1Type(thrift.py3.types.CompiledEnum): - EMPTY = __union1Type.__new__(__union1Type, 0, "EMPTY") - i = __union1Type.__new__(__union1Type, 1, "i") - d = __union1Type.__new__(__union1Type, 2, "d") - - def __cinit__(self, value, name): - if __union1_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"union1.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr + cdef get_by_name(self, str name): + return __union1_union_type_enum_data.get_by_name(name) - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __union1Type): - warnings.warn(f"comparison not supported between instances of { __union1Type } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __union1Type, (self.value,) __SetMetaClass( __union1Type, __union1_Union_TypeMeta) -__union1_Union_TypeEnumMembers = set(__union1Type) - -cdef object __union2_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __union2_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cunion2](), + __union2Type, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __union2_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __union2_Union_TypeEnumMembers: - return value +cdef class __union2_Union_TypeMeta(thrift.py3.types.EnumMeta): - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __union2Type.EMPTY - elif cvalue == 1: - return __union2Type.i - elif cvalue == 2: - return __union2Type.d - elif cvalue == 3: - return __union2Type.s - elif cvalue == 4: - return __union2Type.u - - raise ValueError(f'{value} is not a valid union2.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __union2Type.EMPTY - elif name == "i": - return __union2Type.i - elif name == "d": - return __union2Type.d - elif name == "s": - return __union2Type.s - elif name == "u": - return __union2Type.u - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'i', - 'd', - 's', - 'u', - ] - - @property - def __members__(cls): - return {m.name: m for m in cls} + def __get_by_name(cls, str name): + return __union2_union_type_enum_data.get_by_name(name) - def __iter__(cls): - yield __union2Type.EMPTY - yield __union2Type.i - yield __union2Type.d - yield __union2Type.s - yield __union2Type.u + def __get_by_value(cls, int value): + return __union2_union_type_enum_data.get_by_value(value) - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __union2_Union_TypeEnumMembers + def __get_all_names(cls): + return __union2_union_type_enum_data.get_all_names() def __len__(cls): - return 4+1 # For Empty + return __union2_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __union2Type(thrift.py3.types.CompiledEnum): - EMPTY = __union2Type.__new__(__union2Type, 0, "EMPTY") - i = __union2Type.__new__(__union2Type, 1, "i") - d = __union2Type.__new__(__union2Type, 2, "d") - s = __union2Type.__new__(__union2Type, 3, "s") - u = __union2Type.__new__(__union2Type, 4, "u") - - def __cinit__(self, value, name): - if __union2_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"union2.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" + cdef get_by_name(self, str name): + return __union2_union_type_enum_data.get_by_name(name) - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __union2Type): - warnings.warn(f"comparison not supported between instances of { __union2Type } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __union2Type, (self.value,) __SetMetaClass( __union2Type, __union2_Union_TypeMeta) -__union2_Union_TypeEnumMembers = set(__union2Type) @__cython.auto_pickle(False) @@ -675,7 +318,7 @@ cdef class Internship(thrift.py3.types.Struct): deref(c_inst).title_ref().assign(thrift.py3.types.move(thrift.py3.types.bytes_to_string(title.encode('utf-8')))) deref(c_inst).__isset.title = True if employer is not None: - deref(c_inst).employer_ref().assign(Company_to_cpp(employer)) + deref(c_inst).employer_ref().assign(employer) deref(c_inst).__isset.employer = True # in C++ you don't have to call move(), but this doesn't translate # into a C++ return statement, so you do here diff --git a/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.h b/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.h new file mode 100644 index 00000000000..383369e32af --- /dev/null +++ b/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.h @@ -0,0 +1,21 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::Nada::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} diff --git a/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.pxd index 98d7f53b55f..8f2422ad41b 100644 --- a/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.pyx index b74117dea46..be2d0f8c856 100644 --- a/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/empty-struct/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins @@ -40,90 +44,37 @@ cimport module.types_reflection as _types_reflection -cdef object __Nada_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __Nada_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cNada](), + __NadaType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __Nada_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __Nada_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __NadaType.EMPTY - - raise ValueError(f'{value} is not a valid Nada.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __NadaType.EMPTY - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - ] - - @property - def __members__(cls): - return {m.name: m for m in cls} - - def __iter__(cls): - yield __NadaType.EMPTY - return iter(()) +cdef class __Nada_Union_TypeMeta(thrift.py3.types.EnumMeta): + + def __get_by_name(cls, str name): + return __Nada_union_type_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __Nada_union_type_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __Nada_Union_TypeEnumMembers + def __get_all_names(cls): + return __Nada_union_type_enum_data.get_all_names() def __len__(cls): - return 0+1 # For Empty + return __Nada_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __NadaType(thrift.py3.types.CompiledEnum): - EMPTY = __NadaType.__new__(__NadaType, 0, "EMPTY") - - def __cinit__(self, value, name): - if __Nada_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"Nada.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str + cdef get_by_name(self, str name): + return __Nada_union_type_enum_data.get_by_name(name) - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __NadaType): - warnings.warn(f"comparison not supported between instances of { __NadaType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __NadaType, (self.value,) __SetMetaClass( __NadaType, __Nada_Union_TypeMeta) -__Nada_Union_TypeEnumMembers = set(__NadaType) @__cython.auto_pickle(False) diff --git a/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.h b/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.h new file mode 100644 index 00000000000..af78922d032 --- /dev/null +++ b/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" diff --git a/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.pxd index fbf6ec963d3..253ab186df2 100644 --- a/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.pyx index 4e544b466fd..26e95dc3bad 100644 --- a/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/exceptions/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,13 +37,13 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class Banal(thrift.py3.exceptions.GeneratedError): diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.h b/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.h new file mode 100644 index 00000000000..289675c8280 --- /dev/null +++ b/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "gen-cpp2/includes_types.h" diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.pxd b/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.pxd index 53e358e2792..234b99b5916 100644 --- a/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.pxd +++ b/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.pxd @@ -27,6 +27,8 @@ from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional cimport transitive.types as _transitive_types +cdef extern from "gen-py3/includes/types.h": + pass diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.pyx b/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.pyx index 27fcf302c55..537898f439c 100644 --- a/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.pyx +++ b/thrift/compiler/test/fixtures/includes/gen-py3/includes/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport transitive.types as _transitive_types @@ -41,6 +45,7 @@ import transitive.types as _transitive_types cimport includes.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class Included(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.h b/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.h new file mode 100644 index 00000000000..d3e5ee27ac5 --- /dev/null +++ b/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/matching_struct_names_types.h" diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.pxd b/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.pxd index c3d997fa853..bc45cb33918 100644 --- a/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.pxd +++ b/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.pxd @@ -27,6 +27,8 @@ from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional cimport module.types as _module_types +cdef extern from "src/gen-py3/matching_struct_names/types.h": + pass diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.pyx b/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.pyx index 3e71c45a0e2..1fb3830ccc1 100644 --- a/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.pyx +++ b/thrift/compiler/test/fixtures/includes/gen-py3/matching_struct_names/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types as _module_types @@ -41,6 +45,7 @@ import module.types as _module_types cimport matching_struct_names.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class MyStruct(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/module/types.h b/thrift/compiler/test/fixtures/includes/gen-py3/module/types.h new file mode 100644 index 00000000000..4975a655284 --- /dev/null +++ b/thrift/compiler/test/fixtures/includes/gen-py3/module/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "gen-cpp2/module_types.h" diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/includes/gen-py3/module/types.pxd index 34fbb2bde35..e81898bac79 100644 --- a/thrift/compiler/test/fixtures/includes/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/includes/gen-py3/module/types.pxd @@ -27,6 +27,8 @@ from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional cimport includes.types as _includes_types +cdef extern from "gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/includes/gen-py3/module/types.pyx index cd105e7c7d4..dd4e963962b 100644 --- a/thrift/compiler/test/fixtures/includes/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/includes/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport includes.types as _includes_types @@ -41,6 +45,7 @@ import includes.types as _includes_types cimport module.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class MyStruct(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/service/types.h b/thrift/compiler/test/fixtures/includes/gen-py3/service/types.h new file mode 100644 index 00000000000..eab01d97bb7 --- /dev/null +++ b/thrift/compiler/test/fixtures/includes/gen-py3/service/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/service_types.h" diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/service/types.pxd b/thrift/compiler/test/fixtures/includes/gen-py3/service/types.pxd index ba112d59da2..864a8224a6d 100644 --- a/thrift/compiler/test/fixtures/includes/gen-py3/service/types.pxd +++ b/thrift/compiler/test/fixtures/includes/gen-py3/service/types.pxd @@ -29,6 +29,8 @@ from folly.optional cimport cOptional cimport includes.types as _includes_types cimport module.types as _module_types cimport transitive.types as _transitive_types +cdef extern from "src/gen-py3/service/types.h": + pass diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/service/types.pyx b/thrift/compiler/test/fixtures/includes/gen-py3/service/types.pyx index 72a370b8105..c223b7a66a2 100644 --- a/thrift/compiler/test/fixtures/includes/gen-py3/service/types.pyx +++ b/thrift/compiler/test/fixtures/includes/gen-py3/service/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport includes.types as _includes_types @@ -45,5 +49,6 @@ import transitive.types as _transitive_types cimport service.types_reflection as _types_reflection + IncludesIncluded = _includes_types.Included IncludesTransitiveFoo = _transitive_types.Foo diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.h b/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.h new file mode 100644 index 00000000000..5196148358e --- /dev/null +++ b/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "gen-cpp2/transitive_types.h" diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.pxd b/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.pxd index d3e663ad2e1..7e79c8cb5b2 100644 --- a/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.pxd +++ b/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "gen-py3/transitive/types.h": + pass diff --git a/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.pyx b/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.pyx index 5931dddeae0..d4d4e321225 100644 --- a/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.pyx +++ b/thrift/compiler/test/fixtures/includes/gen-py3/transitive/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,13 +37,13 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport transitive.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class Foo(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.h b/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.h new file mode 100644 index 00000000000..af78922d032 --- /dev/null +++ b/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" diff --git a/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.pxd index 289d905297b..297519cf49c 100644 --- a/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.pyx index d64ecfb1d25..972c156675c 100644 --- a/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/inheritance/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,10 +37,10 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection + diff --git a/thrift/compiler/test/fixtures/list/gen-py3/module/types.h b/thrift/compiler/test/fixtures/list/gen-py3/module/types.h new file mode 100644 index 00000000000..af78922d032 --- /dev/null +++ b/thrift/compiler/test/fixtures/list/gen-py3/module/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" diff --git a/thrift/compiler/test/fixtures/list/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/list/gen-py3/module/types.pxd index c2e56fd3483..e74b835f6c0 100644 --- a/thrift/compiler/test/fixtures/list/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/list/gen-py3/module/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/list/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/list/gen-py3/module/types.pyx index a0233c4a19c..562f7a2dc5c 100644 --- a/thrift/compiler/test/fixtures/list/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/list/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,13 +37,13 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class List__string(thrift.py3.types.Container): def __init__(self, items=None): diff --git a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.h b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.h new file mode 100644 index 00000000000..33517d94bc4 --- /dev/null +++ b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.h @@ -0,0 +1,22 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "gen-cpp2/includes_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::a::different::ns::AnEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + diff --git a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.pxd b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.pxd index eaf84a6809c..f704cb6d6c5 100644 --- a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.pxd +++ b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.pxd @@ -26,16 +26,16 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "gen-py3/includes/types.h": + pass cdef extern from "folly/sorted_vector_types.h": pass cdef extern from "gen-cpp2/includes_types.h" namespace "::a::different::ns": cdef cppclass cAnEnum "::a::different::ns::AnEnum": - bint operator==(cAnEnum&) - bint operator!=(cAnEnum&) - cAnEnum AnEnum__FIELDA "::a::different::ns::AnEnum::FIELDA" - cAnEnum AnEnum__FIELDB "::a::different::ns::AnEnum::FIELDB" + pass + @@ -43,11 +43,6 @@ cdef extern from "gen-cpp2/includes_types.h" namespace "::a::different::ns": cdef class AnEnum(thrift.py3.types.CompiledEnum): pass - -cdef cAnEnum AnEnum_to_cpp(AnEnum value) - - - cdef extern from "gen-cpp2/includes_types_custom_protocol.h" namespace "::a::different::ns": cdef cppclass cAStruct__isset "::a::different::ns::AStruct::__isset": bint FieldA diff --git a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.pyx b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.pyx index 54861ada779..694497ad830 100644 --- a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.pyx +++ b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/includes/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,112 +37,43 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport includes.types_reflection as _types_reflection -cdef object __AnEnumEnumInstances = None # Set[AnEnum] -cdef object __AnEnumEnumMembers = {} # Dict[str, AnEnum] -cdef object __AnEnumEnumUniqueValues = dict() # Dict[int, AnEnum] + +cdef __EnumData __AnEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cAnEnum](), AnEnum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __AnEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 2: - return AnEnum.FIELDA - elif cvalue == 4: - return AnEnum.FIELDB - - raise ValueError(f'{value} is not a valid AnEnum') - - def __getitem__(cls, name): - return __AnEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'FIELDA', - 'FIELDB', - ] - - def __iter__(cls): - return iter(__AnEnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __AnEnumEnumInstances +cdef class __AnEnumMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__AnEnumEnumInstances) + def __get_by_name(cls, str name): + return __AnEnum_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __AnEnum_enum_data.get_by_value(value) -cdef __AnEnum_unique_instance(int value, str name): - inst = __AnEnumEnumUniqueValues.get(value) - if inst is None: - inst = __AnEnumEnumUniqueValues[value] = AnEnum.__new__(AnEnum, value, name) - __AnEnumEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __AnEnum_enum_data.get_all_names() + + def __len__(cls): + return __AnEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class AnEnum(thrift.py3.types.CompiledEnum): - FIELDA = __AnEnum_unique_instance(2, "FIELDA") - FIELDB = __AnEnum_unique_instance(4, "FIELDB") - __members__ = thrift.py3.types.MappingProxyType(__AnEnumEnumMembers) - - def __cinit__(self, value, name): - if __AnEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"AnEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, AnEnum): - warnings.warn(f"comparison not supported between instances of { AnEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash + cdef get_by_name(self, str name): + return __AnEnum_enum_data.get_by_name(name) - def __reduce__(self): - return AnEnum, (self.value,) __SetMetaClass( AnEnum, __AnEnumMeta) -__AnEnumEnumInstances = set(__AnEnumEnumUniqueValues.values()) -cdef inline cAnEnum AnEnum_to_cpp(AnEnum value): - cdef int cvalue = value.value - if cvalue == 2: - return AnEnum__FIELDA - elif cvalue == 4: - return AnEnum__FIELDB @__cython.auto_pickle(False) cdef class AStruct(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/clients.pyx b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/clients.pyx index 21dbfff7581..5984f4096a1 100644 --- a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/clients.pyx +++ b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/clients.pyx @@ -1346,7 +1346,7 @@ cdef class ParamService(thrift.py3.client.Client): bridgeFutureWith[cFollyUnit]( self._executor, down_cast_ptr[cParamServiceClientWrapper, cClientWrapper](self._client.get()).void_ret_enum_param(rpc_options._cpp_obj, - _module_types.MyEnumA_to_cpp(param1), + <_module_types.cMyEnumA>param1, ), ParamService_void_ret_enum_param_callback, __userdata @@ -1808,7 +1808,7 @@ cdef class ParamService(thrift.py3.client.Client): self._executor, down_cast_ptr[cParamServiceClientWrapper, cClientWrapper](self._client.get()).enum_ret_double_enum_param(rpc_options._cpp_obj, param1, - _module_types.MyEnumA_to_cpp(param2), + <_module_types.cMyEnumA>param2, ), ParamService_enum_ret_double_enum_param_callback, __userdata diff --git a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/services.pyx b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/services.pyx index 698df88f619..b781c7e5213 100644 --- a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/services.pyx +++ b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/services.pyx @@ -1490,7 +1490,7 @@ async def ReturnService_enumReturn_coro( cTApplicationExceptionType__UNKNOWN, repr(ex).encode('UTF-8') )) else: - promise.cPromise.setValue(_module_types.MyEnumA_to_cpp(result)) + promise.cPromise.setValue(<_module_types.cMyEnumA>result) cdef api void call_cy_ReturnService_list_EnumReturn( object self, @@ -3087,7 +3087,7 @@ async def ParamService_enum_ret_double_param_coro( cTApplicationExceptionType__UNKNOWN, repr(ex).encode('UTF-8') )) else: - promise.cPromise.setValue(_module_types.MyEnumA_to_cpp(result)) + promise.cPromise.setValue(<_module_types.cMyEnumA>result) cdef api void call_cy_ParamService_enum_ret_double_enum_param( object self, @@ -3145,7 +3145,7 @@ async def ParamService_enum_ret_double_enum_param_coro( cTApplicationExceptionType__UNKNOWN, repr(ex).encode('UTF-8') )) else: - promise.cPromise.setValue(_module_types.MyEnumA_to_cpp(result)) + promise.cPromise.setValue(<_module_types.cMyEnumA>result) cdef api void call_cy_ParamService_listenum_ret_map_param( object self, diff --git a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.h b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.h new file mode 100644 index 00000000000..9b51fc4163b --- /dev/null +++ b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.h @@ -0,0 +1,85 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::some::valid::ns::MyEnumA>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::some::valid::ns::AnnotatedEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::some::valid::ns::AnnotatedEnum2>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::some::valid::ns::MyEnumB>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::some::valid::ns::SimpleUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::some::valid::ns::ComplexUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::some::valid::ns::FloatUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} diff --git a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.pxd index 17eebac33d7..aa69b53d6cb 100644 --- a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.pxd @@ -27,6 +27,8 @@ from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional cimport includes.types as _includes_types +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from "": pass @@ -281,27 +283,17 @@ cdef extern from *: cdef extern from "src/gen-cpp2/module_types.h" namespace "::some::valid::ns": cdef cppclass cMyEnumA "::some::valid::ns::MyEnumA": - bint operator==(cMyEnumA&) - bint operator!=(cMyEnumA&) - cMyEnumA MyEnumA__fieldA "::some::valid::ns::MyEnumA::fieldA" - cMyEnumA MyEnumA__fieldB "::some::valid::ns::MyEnumA::fieldB" - cMyEnumA MyEnumA__fieldC "::some::valid::ns::MyEnumA::fieldC" + pass + cdef cppclass cAnnotatedEnum "::some::valid::ns::AnnotatedEnum": - bint operator==(cAnnotatedEnum&) - bint operator!=(cAnnotatedEnum&) - cAnnotatedEnum AnnotatedEnum__FIELDA "::some::valid::ns::AnnotatedEnum::FIELDA" - cAnnotatedEnum AnnotatedEnum__FIELDB "::some::valid::ns::AnnotatedEnum::FIELDB" - cAnnotatedEnum AnnotatedEnum__FIELDC "::some::valid::ns::AnnotatedEnum::FIELDC" + pass + cdef cppclass cAnnotatedEnum2 "::some::valid::ns::AnnotatedEnum2": - bint operator==(cAnnotatedEnum2&) - bint operator!=(cAnnotatedEnum2&) - cAnnotatedEnum2 AnnotatedEnum2__FIELDA "::some::valid::ns::AnnotatedEnum2::FIELDA" - cAnnotatedEnum2 AnnotatedEnum2__FIELDB "::some::valid::ns::AnnotatedEnum2::FIELDB" - cAnnotatedEnum2 AnnotatedEnum2__FIELDC "::some::valid::ns::AnnotatedEnum2::FIELDC" + pass + cdef cppclass cMyEnumB "::some::valid::ns::MyEnumB": - bint operator==(cMyEnumB&) - bint operator!=(cMyEnumB&) - cMyEnumB MyEnumB__AField "::some::valid::ns::MyEnumB::AField" + pass + @@ -310,37 +302,17 @@ cdef class MyEnumA(thrift.py3.types.CompiledEnum): pass -cdef cMyEnumA MyEnumA_to_cpp(MyEnumA value) - - - - cdef class AnnotatedEnum(thrift.py3.types.CompiledEnum): pass -cdef cAnnotatedEnum AnnotatedEnum_to_cpp(AnnotatedEnum value) - - - - cdef class AnnotatedEnum2(thrift.py3.types.CompiledEnum): pass -cdef cAnnotatedEnum2 AnnotatedEnum2_to_cpp(AnnotatedEnum2 value) - - - - cdef class MyEnumB(thrift.py3.types.CompiledEnum): pass - -cdef cMyEnumB MyEnumB_to_cpp(MyEnumB value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::some::valid::ns": cdef cppclass cEmpty__isset "::some::valid::ns::Empty::__isset": pass diff --git a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.pyx index 56e93d22d61..4443fc9ec0f 100644 --- a/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/mcpp2-compare/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport includes.types as _includes_types @@ -40,892 +44,229 @@ import includes.types as _includes_types cimport module.types_reflection as _types_reflection -cdef object __MyEnumAEnumInstances = None # Set[MyEnumA] -cdef object __MyEnumAEnumMembers = {} # Dict[str, MyEnumA] -cdef object __MyEnumAEnumUniqueValues = dict() # Dict[int, MyEnumA] + +cdef __EnumData __MyEnumA_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cMyEnumA](), MyEnumA) + @__cython.internal @__cython.auto_pickle(False) -cdef class __MyEnumAMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 1: - return MyEnumA.fieldA - elif cvalue == 2: - return MyEnumA.fieldB - elif cvalue == 4: - return MyEnumA.fieldC - - raise ValueError(f'{value} is not a valid MyEnumA') - - def __getitem__(cls, name): - return __MyEnumAEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'fieldA', - 'fieldB', - 'fieldC', - ] - - def __iter__(cls): - return iter(__MyEnumAEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyEnumAEnumInstances +cdef class __MyEnumAMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__MyEnumAEnumInstances) + def __get_by_name(cls, str name): + return __MyEnumA_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __MyEnumA_enum_data.get_by_value(value) -cdef __MyEnumA_unique_instance(int value, str name): - inst = __MyEnumAEnumUniqueValues.get(value) - if inst is None: - inst = __MyEnumAEnumUniqueValues[value] = MyEnumA.__new__(MyEnumA, value, name) - __MyEnumAEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __MyEnumA_enum_data.get_all_names() + + def __len__(cls): + return __MyEnumA_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class MyEnumA(thrift.py3.types.CompiledEnum): - fieldA = __MyEnumA_unique_instance(1, "fieldA") - fieldB = __MyEnumA_unique_instance(2, "fieldB") - fieldC = __MyEnumA_unique_instance(4, "fieldC") - __members__ = thrift.py3.types.MappingProxyType(__MyEnumAEnumMembers) - - def __cinit__(self, value, name): - if __MyEnumAEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyEnumA.{name}" - self.__repr = f"<{self.__str}: {value}>" + cdef get_by_name(self, str name): + return __MyEnumA_enum_data.get_by_name(name) - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, MyEnumA): - warnings.warn(f"comparison not supported between instances of { MyEnumA } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return MyEnumA, (self.value,) __SetMetaClass( MyEnumA, __MyEnumAMeta) -__MyEnumAEnumInstances = set(__MyEnumAEnumUniqueValues.values()) -cdef inline cMyEnumA MyEnumA_to_cpp(MyEnumA value): - cdef int cvalue = value.value - if cvalue == 1: - return MyEnumA__fieldA - elif cvalue == 2: - return MyEnumA__fieldB - elif cvalue == 4: - return MyEnumA__fieldC -cdef object __AnnotatedEnumEnumInstances = None # Set[AnnotatedEnum] -cdef object __AnnotatedEnumEnumMembers = {} # Dict[str, AnnotatedEnum] -cdef object __AnnotatedEnumEnumUniqueValues = dict() # Dict[int, AnnotatedEnum] +cdef __EnumData __AnnotatedEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cAnnotatedEnum](), AnnotatedEnum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __AnnotatedEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 2: - return AnnotatedEnum.FIELDA - elif cvalue == 4: - return AnnotatedEnum.FIELDB - elif cvalue == 9: - return AnnotatedEnum.FIELDC - - raise ValueError(f'{value} is not a valid AnnotatedEnum') - - def __getitem__(cls, name): - return __AnnotatedEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'FIELDA', - 'FIELDB', - 'FIELDC', - ] - - def __iter__(cls): - return iter(__AnnotatedEnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __AnnotatedEnumEnumInstances +cdef class __AnnotatedEnumMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__AnnotatedEnumEnumInstances) + def __get_by_name(cls, str name): + return __AnnotatedEnum_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __AnnotatedEnum_enum_data.get_by_value(value) -cdef __AnnotatedEnum_unique_instance(int value, str name): - inst = __AnnotatedEnumEnumUniqueValues.get(value) - if inst is None: - inst = __AnnotatedEnumEnumUniqueValues[value] = AnnotatedEnum.__new__(AnnotatedEnum, value, name) - __AnnotatedEnumEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __AnnotatedEnum_enum_data.get_all_names() + + def __len__(cls): + return __AnnotatedEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class AnnotatedEnum(thrift.py3.types.CompiledEnum): - FIELDA = __AnnotatedEnum_unique_instance(2, "FIELDA") - FIELDB = __AnnotatedEnum_unique_instance(4, "FIELDB") - FIELDC = __AnnotatedEnum_unique_instance(9, "FIELDC") - __members__ = thrift.py3.types.MappingProxyType(__AnnotatedEnumEnumMembers) - - def __cinit__(self, value, name): - if __AnnotatedEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"AnnotatedEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, AnnotatedEnum): - warnings.warn(f"comparison not supported between instances of { AnnotatedEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other + cdef get_by_name(self, str name): + return __AnnotatedEnum_enum_data.get_by_name(name) - def __hash__(self): - return self.__hash - - def __reduce__(self): - return AnnotatedEnum, (self.value,) __SetMetaClass( AnnotatedEnum, __AnnotatedEnumMeta) -__AnnotatedEnumEnumInstances = set(__AnnotatedEnumEnumUniqueValues.values()) -cdef inline cAnnotatedEnum AnnotatedEnum_to_cpp(AnnotatedEnum value): - cdef int cvalue = value.value - if cvalue == 2: - return AnnotatedEnum__FIELDA - elif cvalue == 4: - return AnnotatedEnum__FIELDB - elif cvalue == 9: - return AnnotatedEnum__FIELDC -cdef object __AnnotatedEnum2EnumInstances = None # Set[AnnotatedEnum2] -cdef object __AnnotatedEnum2EnumMembers = {} # Dict[str, AnnotatedEnum2] -cdef object __AnnotatedEnum2EnumUniqueValues = dict() # Dict[int, AnnotatedEnum2] +cdef __EnumData __AnnotatedEnum2_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cAnnotatedEnum2](), AnnotatedEnum2) + @__cython.internal @__cython.auto_pickle(False) -cdef class __AnnotatedEnum2Meta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 2: - return AnnotatedEnum2.FIELDA - elif cvalue == 4: - return AnnotatedEnum2.FIELDB - elif cvalue == 9: - return AnnotatedEnum2.FIELDC - - raise ValueError(f'{value} is not a valid AnnotatedEnum2') - - def __getitem__(cls, name): - return __AnnotatedEnum2EnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'FIELDA', - 'FIELDB', - 'FIELDC', - ] - - def __iter__(cls): - return iter(__AnnotatedEnum2EnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __AnnotatedEnum2EnumInstances +cdef class __AnnotatedEnum2Meta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__AnnotatedEnum2EnumInstances) + def __get_by_name(cls, str name): + return __AnnotatedEnum2_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __AnnotatedEnum2_enum_data.get_by_value(value) -cdef __AnnotatedEnum2_unique_instance(int value, str name): - inst = __AnnotatedEnum2EnumUniqueValues.get(value) - if inst is None: - inst = __AnnotatedEnum2EnumUniqueValues[value] = AnnotatedEnum2.__new__(AnnotatedEnum2, value, name) - __AnnotatedEnum2EnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __AnnotatedEnum2_enum_data.get_all_names() + + def __len__(cls): + return __AnnotatedEnum2_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class AnnotatedEnum2(thrift.py3.types.CompiledEnum): - FIELDA = __AnnotatedEnum2_unique_instance(2, "FIELDA") - FIELDB = __AnnotatedEnum2_unique_instance(4, "FIELDB") - FIELDC = __AnnotatedEnum2_unique_instance(9, "FIELDC") - __members__ = thrift.py3.types.MappingProxyType(__AnnotatedEnum2EnumMembers) - - def __cinit__(self, value, name): - if __AnnotatedEnum2EnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"AnnotatedEnum2.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str + cdef get_by_name(self, str name): + return __AnnotatedEnum2_enum_data.get_by_name(name) - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, AnnotatedEnum2): - warnings.warn(f"comparison not supported between instances of { AnnotatedEnum2 } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return AnnotatedEnum2, (self.value,) __SetMetaClass( AnnotatedEnum2, __AnnotatedEnum2Meta) -__AnnotatedEnum2EnumInstances = set(__AnnotatedEnum2EnumUniqueValues.values()) -cdef inline cAnnotatedEnum2 AnnotatedEnum2_to_cpp(AnnotatedEnum2 value): - cdef int cvalue = value.value - if cvalue == 2: - return AnnotatedEnum2__FIELDA - elif cvalue == 4: - return AnnotatedEnum2__FIELDB - elif cvalue == 9: - return AnnotatedEnum2__FIELDC -cdef object __MyEnumBEnumInstances = None # Set[MyEnumB] -cdef object __MyEnumBEnumMembers = {} # Dict[str, MyEnumB] -cdef object __MyEnumBEnumUniqueValues = dict() # Dict[int, MyEnumB] +cdef __EnumData __MyEnumB_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cMyEnumB](), MyEnumB) + @__cython.internal @__cython.auto_pickle(False) -cdef class __MyEnumBMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return MyEnumB.AField - - raise ValueError(f'{value} is not a valid MyEnumB') +cdef class __MyEnumBMeta(thrift.py3.types.EnumMeta): - def __getitem__(cls, name): - return __MyEnumBEnumMembers[name] + def __get_by_name(cls, str name): + return __MyEnumB_enum_data.get_by_name(name) - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'AField', - ] + def __get_by_value(cls, int value): + return __MyEnumB_enum_data.get_by_value(value) - def __iter__(cls): - return iter(__MyEnumBEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyEnumBEnumInstances + def __get_all_names(cls): + return __MyEnumB_enum_data.get_all_names() def __len__(cls): - return len(__MyEnumBEnumInstances) - - -cdef __MyEnumB_unique_instance(int value, str name): - inst = __MyEnumBEnumUniqueValues.get(value) - if inst is None: - inst = __MyEnumBEnumUniqueValues[value] = MyEnumB.__new__(MyEnumB, value, name) - __MyEnumBEnumMembers[name] = inst - return inst + return __MyEnumB_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class MyEnumB(thrift.py3.types.CompiledEnum): - AField = __MyEnumB_unique_instance(0, "AField") - __members__ = thrift.py3.types.MappingProxyType(__MyEnumBEnumMembers) - - def __cinit__(self, value, name): - if __MyEnumBEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyEnumB.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr + cdef get_by_name(self, str name): + return __MyEnumB_enum_data.get_by_name(name) - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, MyEnumB): - warnings.warn(f"comparison not supported between instances of { MyEnumB } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return MyEnumB, (self.value,) __SetMetaClass( MyEnumB, __MyEnumBMeta) -__MyEnumBEnumInstances = set(__MyEnumBEnumUniqueValues.values()) -cdef inline cMyEnumB MyEnumB_to_cpp(MyEnumB value): - cdef int cvalue = value.value - if cvalue == 0: - return MyEnumB__AField - -cdef object __SimpleUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __SimpleUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cSimpleUnion](), + __SimpleUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __SimpleUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __SimpleUnion_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __SimpleUnionType.EMPTY - elif cvalue == 7: - return __SimpleUnionType.intValue - elif cvalue == 2: - return __SimpleUnionType.stringValue - - raise ValueError(f'{value} is not a valid SimpleUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __SimpleUnionType.EMPTY - elif name == "intValue": - return __SimpleUnionType.intValue - elif name == "stringValue": - return __SimpleUnionType.stringValue - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'intValue', - 'stringValue', - ] +cdef class __SimpleUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - @property - def __members__(cls): - return {m.name: m for m in cls} - - def __iter__(cls): - yield __SimpleUnionType.EMPTY - yield __SimpleUnionType.intValue - yield __SimpleUnionType.stringValue + def __get_by_name(cls, str name): + return __SimpleUnion_union_type_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __SimpleUnion_union_type_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __SimpleUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __SimpleUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 2+1 # For Empty + return __SimpleUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __SimpleUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __SimpleUnionType.__new__(__SimpleUnionType, 0, "EMPTY") - intValue = __SimpleUnionType.__new__(__SimpleUnionType, 7, "intValue") - stringValue = __SimpleUnionType.__new__(__SimpleUnionType, 2, "stringValue") - - def __cinit__(self, value, name): - if __SimpleUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"SimpleUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" + cdef get_by_name(self, str name): + return __SimpleUnion_union_type_enum_data.get_by_name(name) - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __SimpleUnionType): - warnings.warn(f"comparison not supported between instances of { __SimpleUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __SimpleUnionType, (self.value,) __SetMetaClass( __SimpleUnionType, __SimpleUnion_Union_TypeMeta) -__SimpleUnion_Union_TypeEnumMembers = set(__SimpleUnionType) - -cdef object __ComplexUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __ComplexUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cComplexUnion](), + __ComplexUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __ComplexUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __ComplexUnion_Union_TypeEnumMembers: - return value +cdef class __ComplexUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __ComplexUnionType.EMPTY - elif cvalue == 1: - return __ComplexUnionType.intValue - elif cvalue == 201: - return __ComplexUnionType.opt_intValue - elif cvalue == 3: - return __ComplexUnionType.stringValue - elif cvalue == 203: - return __ComplexUnionType.opt_stringValue - elif cvalue == 4: - return __ComplexUnionType.intValue2 - elif cvalue == 6: - return __ComplexUnionType.intValue3 - elif cvalue == 7: - return __ComplexUnionType.doubelValue - elif cvalue == 8: - return __ComplexUnionType.boolValue - elif cvalue == 9: - return __ComplexUnionType.union_list - elif cvalue == 10: - return __ComplexUnionType.union_set - elif cvalue == 11: - return __ComplexUnionType.union_map - elif cvalue == 211: - return __ComplexUnionType.opt_union_map - elif cvalue == 12: - return __ComplexUnionType.enum_field - elif cvalue == 13: - return __ComplexUnionType.enum_container - elif cvalue == 14: - return __ComplexUnionType.a_struct - elif cvalue == 15: - return __ComplexUnionType.a_set_struct - elif cvalue == 16: - return __ComplexUnionType.a_union - elif cvalue == 216: - return __ComplexUnionType.opt_a_union - elif cvalue == 17: - return __ComplexUnionType.a_union_list - elif cvalue == 18: - return __ComplexUnionType.a_union_typedef - elif cvalue == 19: - return __ComplexUnionType.a_union_typedef_list - elif cvalue == 20: - return __ComplexUnionType.MyBinaryField - elif cvalue == 21: - return __ComplexUnionType.MyBinaryField2 - elif cvalue == 23: - return __ComplexUnionType.MyBinaryListField4 - elif cvalue == 24: - return __ComplexUnionType.ref_field - elif cvalue == 25: - return __ComplexUnionType.ref_field2 - elif cvalue == 26: - return __ComplexUnionType.excp_field - - raise ValueError(f'{value} is not a valid ComplexUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __ComplexUnionType.EMPTY - elif name == "intValue": - return __ComplexUnionType.intValue - elif name == "opt_intValue": - return __ComplexUnionType.opt_intValue - elif name == "stringValue": - return __ComplexUnionType.stringValue - elif name == "opt_stringValue": - return __ComplexUnionType.opt_stringValue - elif name == "intValue2": - return __ComplexUnionType.intValue2 - elif name == "intValue3": - return __ComplexUnionType.intValue3 - elif name == "doubelValue": - return __ComplexUnionType.doubelValue - elif name == "boolValue": - return __ComplexUnionType.boolValue - elif name == "union_list": - return __ComplexUnionType.union_list - elif name == "union_set": - return __ComplexUnionType.union_set - elif name == "union_map": - return __ComplexUnionType.union_map - elif name == "opt_union_map": - return __ComplexUnionType.opt_union_map - elif name == "enum_field": - return __ComplexUnionType.enum_field - elif name == "enum_container": - return __ComplexUnionType.enum_container - elif name == "a_struct": - return __ComplexUnionType.a_struct - elif name == "a_set_struct": - return __ComplexUnionType.a_set_struct - elif name == "a_union": - return __ComplexUnionType.a_union - elif name == "opt_a_union": - return __ComplexUnionType.opt_a_union - elif name == "a_union_list": - return __ComplexUnionType.a_union_list - elif name == "a_union_typedef": - return __ComplexUnionType.a_union_typedef - elif name == "a_union_typedef_list": - return __ComplexUnionType.a_union_typedef_list - elif name == "MyBinaryField": - return __ComplexUnionType.MyBinaryField - elif name == "MyBinaryField2": - return __ComplexUnionType.MyBinaryField2 - elif name == "MyBinaryListField4": - return __ComplexUnionType.MyBinaryListField4 - elif name == "ref_field": - return __ComplexUnionType.ref_field - elif name == "ref_field2": - return __ComplexUnionType.ref_field2 - elif name == "excp_field": - return __ComplexUnionType.excp_field - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'intValue', - 'opt_intValue', - 'stringValue', - 'opt_stringValue', - 'intValue2', - 'intValue3', - 'doubelValue', - 'boolValue', - 'union_list', - 'union_set', - 'union_map', - 'opt_union_map', - 'enum_field', - 'enum_container', - 'a_struct', - 'a_set_struct', - 'a_union', - 'opt_a_union', - 'a_union_list', - 'a_union_typedef', - 'a_union_typedef_list', - 'MyBinaryField', - 'MyBinaryField2', - 'MyBinaryListField4', - 'ref_field', - 'ref_field2', - 'excp_field', - ] + def __get_by_name(cls, str name): + return __ComplexUnion_union_type_enum_data.get_by_name(name) - @property - def __members__(cls): - return {m.name: m for m in cls} - - def __iter__(cls): - yield __ComplexUnionType.EMPTY - yield __ComplexUnionType.intValue - yield __ComplexUnionType.opt_intValue - yield __ComplexUnionType.stringValue - yield __ComplexUnionType.opt_stringValue - yield __ComplexUnionType.intValue2 - yield __ComplexUnionType.intValue3 - yield __ComplexUnionType.doubelValue - yield __ComplexUnionType.boolValue - yield __ComplexUnionType.union_list - yield __ComplexUnionType.union_set - yield __ComplexUnionType.union_map - yield __ComplexUnionType.opt_union_map - yield __ComplexUnionType.enum_field - yield __ComplexUnionType.enum_container - yield __ComplexUnionType.a_struct - yield __ComplexUnionType.a_set_struct - yield __ComplexUnionType.a_union - yield __ComplexUnionType.opt_a_union - yield __ComplexUnionType.a_union_list - yield __ComplexUnionType.a_union_typedef - yield __ComplexUnionType.a_union_typedef_list - yield __ComplexUnionType.MyBinaryField - yield __ComplexUnionType.MyBinaryField2 - yield __ComplexUnionType.MyBinaryListField4 - yield __ComplexUnionType.ref_field - yield __ComplexUnionType.ref_field2 - yield __ComplexUnionType.excp_field - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __ComplexUnion_Union_TypeEnumMembers + def __get_by_value(cls, int value): + return __ComplexUnion_union_type_enum_data.get_by_value(value) + + def __get_all_names(cls): + return __ComplexUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 27+1 # For Empty + return __ComplexUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __ComplexUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __ComplexUnionType.__new__(__ComplexUnionType, 0, "EMPTY") - intValue = __ComplexUnionType.__new__(__ComplexUnionType, 1, "intValue") - opt_intValue = __ComplexUnionType.__new__(__ComplexUnionType, 201, "opt_intValue") - stringValue = __ComplexUnionType.__new__(__ComplexUnionType, 3, "stringValue") - opt_stringValue = __ComplexUnionType.__new__(__ComplexUnionType, 203, "opt_stringValue") - intValue2 = __ComplexUnionType.__new__(__ComplexUnionType, 4, "intValue2") - intValue3 = __ComplexUnionType.__new__(__ComplexUnionType, 6, "intValue3") - doubelValue = __ComplexUnionType.__new__(__ComplexUnionType, 7, "doubelValue") - boolValue = __ComplexUnionType.__new__(__ComplexUnionType, 8, "boolValue") - union_list = __ComplexUnionType.__new__(__ComplexUnionType, 9, "union_list") - union_set = __ComplexUnionType.__new__(__ComplexUnionType, 10, "union_set") - union_map = __ComplexUnionType.__new__(__ComplexUnionType, 11, "union_map") - opt_union_map = __ComplexUnionType.__new__(__ComplexUnionType, 211, "opt_union_map") - enum_field = __ComplexUnionType.__new__(__ComplexUnionType, 12, "enum_field") - enum_container = __ComplexUnionType.__new__(__ComplexUnionType, 13, "enum_container") - a_struct = __ComplexUnionType.__new__(__ComplexUnionType, 14, "a_struct") - a_set_struct = __ComplexUnionType.__new__(__ComplexUnionType, 15, "a_set_struct") - a_union = __ComplexUnionType.__new__(__ComplexUnionType, 16, "a_union") - opt_a_union = __ComplexUnionType.__new__(__ComplexUnionType, 216, "opt_a_union") - a_union_list = __ComplexUnionType.__new__(__ComplexUnionType, 17, "a_union_list") - a_union_typedef = __ComplexUnionType.__new__(__ComplexUnionType, 18, "a_union_typedef") - a_union_typedef_list = __ComplexUnionType.__new__(__ComplexUnionType, 19, "a_union_typedef_list") - MyBinaryField = __ComplexUnionType.__new__(__ComplexUnionType, 20, "MyBinaryField") - MyBinaryField2 = __ComplexUnionType.__new__(__ComplexUnionType, 21, "MyBinaryField2") - MyBinaryListField4 = __ComplexUnionType.__new__(__ComplexUnionType, 23, "MyBinaryListField4") - ref_field = __ComplexUnionType.__new__(__ComplexUnionType, 24, "ref_field") - ref_field2 = __ComplexUnionType.__new__(__ComplexUnionType, 25, "ref_field2") - excp_field = __ComplexUnionType.__new__(__ComplexUnionType, 26, "excp_field") - - def __cinit__(self, value, name): - if __ComplexUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"ComplexUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __ComplexUnionType): - warnings.warn(f"comparison not supported between instances of { __ComplexUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash + cdef get_by_name(self, str name): + return __ComplexUnion_union_type_enum_data.get_by_name(name) - def __reduce__(self): - return __ComplexUnionType, (self.value,) __SetMetaClass( __ComplexUnionType, __ComplexUnion_Union_TypeMeta) -__ComplexUnion_Union_TypeEnumMembers = set(__ComplexUnionType) - -cdef object __FloatUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __FloatUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cFloatUnion](), + __FloatUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __FloatUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __FloatUnion_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __FloatUnionType.EMPTY - elif cvalue == 1: - return __FloatUnionType.floatSide - elif cvalue == 2: - return __FloatUnionType.doubleSide - - raise ValueError(f'{value} is not a valid FloatUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __FloatUnionType.EMPTY - elif name == "floatSide": - return __FloatUnionType.floatSide - elif name == "doubleSide": - return __FloatUnionType.doubleSide - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'floatSide', - 'doubleSide', - ] - - @property - def __members__(cls): - return {m.name: m for m in cls} +cdef class __FloatUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - def __iter__(cls): - yield __FloatUnionType.EMPTY - yield __FloatUnionType.floatSide - yield __FloatUnionType.doubleSide + def __get_by_name(cls, str name): + return __FloatUnion_union_type_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __FloatUnion_union_type_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __FloatUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __FloatUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 2+1 # For Empty + return __FloatUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __FloatUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __FloatUnionType.__new__(__FloatUnionType, 0, "EMPTY") - floatSide = __FloatUnionType.__new__(__FloatUnionType, 1, "floatSide") - doubleSide = __FloatUnionType.__new__(__FloatUnionType, 2, "doubleSide") - - def __cinit__(self, value, name): - if __FloatUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"FloatUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __FloatUnionType): - warnings.warn(f"comparison not supported between instances of { __FloatUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other + cdef get_by_name(self, str name): + return __FloatUnion_union_type_enum_data.get_by_name(name) - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __FloatUnionType, (self.value,) __SetMetaClass( __FloatUnionType, __FloatUnion_Union_TypeMeta) -__FloatUnion_Union_TypeEnumMembers = set(__FloatUnionType) @__cython.auto_pickle(False) @@ -2335,7 +1676,7 @@ cdef class ComplexUnion(thrift.py3.types.Union): if enum_field is not None: if any_set: raise TypeError("At most one field may be set when initializing a union") - deref(c_inst).set_enum_field(MyEnumA_to_cpp(enum_field)) + deref(c_inst).set_enum_field(enum_field) any_set = True if enum_container is not None: if any_set: @@ -2845,7 +2186,7 @@ cdef class AnException(thrift.py3.exceptions.GeneratedError): if req_exception_map is not None: deref(c_inst).req_exception_map = deref(Map__string_i32(req_exception_map)._cpp_obj) if enum_field is not None: - deref(c_inst).enum_field_ref().assign(MyEnumA_to_cpp(enum_field)) + deref(c_inst).enum_field_ref().assign(enum_field) deref(c_inst).__isset.enum_field = True if enum_container is not None: deref(c_inst).enum_container_ref().assign(deref(List__MyEnumA(enum_container)._cpp_obj)) @@ -4180,18 +3521,18 @@ cdef class containerStruct(thrift.py3.types.Struct): deref(c_inst).fieldP_ref().assign(deref(List__List__List__Map__Empty_MyStruct(fieldP)._cpp_obj)) deref(c_inst).__isset.fieldP = True if fieldQ is not None: - deref(c_inst).fieldQ_ref().assign(MyEnumA_to_cpp(fieldQ)) + deref(c_inst).fieldQ_ref().assign(fieldQ) deref(c_inst).__isset.fieldQ = True if fieldR is not None: - deref(c_inst).fieldR_ref().assign(MyEnumA_to_cpp(fieldR)) + deref(c_inst).fieldR_ref().assign(fieldR) deref(c_inst).__isset.fieldR = True if req_fieldR is not None: - deref(c_inst).req_fieldR = MyEnumA_to_cpp(req_fieldR) + deref(c_inst).req_fieldR = req_fieldR if opt_fieldR is not None: - deref(c_inst).opt_fieldR_ref().assign(MyEnumA_to_cpp(opt_fieldR)) + deref(c_inst).opt_fieldR_ref().assign(opt_fieldR) deref(c_inst).__isset.opt_fieldR = True if fieldS is not None: - deref(c_inst).fieldS_ref().assign(MyEnumA_to_cpp(fieldS)) + deref(c_inst).fieldS_ref().assign(fieldS) deref(c_inst).__isset.fieldS = True if fieldT is not None: deref(c_inst).fieldT_ref().assign(deref(List__MyEnumA(fieldT)._cpp_obj)) @@ -4231,10 +3572,10 @@ cdef class containerStruct(thrift.py3.types.Struct): deref(c_inst).fieldAB_ref().assign(deref(Map__Bar__double_Baz__i32(fieldAB)._cpp_obj)) deref(c_inst).__isset.fieldAB = True if fieldAC is not None: - deref(c_inst).fieldAC_ref().assign(MyEnumB_to_cpp(fieldAC)) + deref(c_inst).fieldAC_ref().assign(fieldAC) deref(c_inst).__isset.fieldAC = True if fieldAD is not None: - deref(c_inst).fieldAD_ref().assign(_includes_types.AnEnum_to_cpp(fieldAD)) + deref(c_inst).fieldAD_ref().assign(<_includes_types.cAnEnum>fieldAD) deref(c_inst).__isset.fieldAD = True if fieldAE is not None: deref(c_inst).fieldAE_ref().assign(deref(Map__string_i32(fieldAE)._cpp_obj)) @@ -8145,7 +7486,7 @@ cdef class List__MyEnumA(thrift.py3.types.Container): for item in items: if not isinstance(item, MyEnumA): raise TypeError(f"{item!r} is not of type MyEnumA") - deref(c_inst).push_back(MyEnumA_to_cpp(item)) + deref(c_inst).push_back(item) return c_inst def __add__(object self, object other): @@ -8204,7 +7545,7 @@ cdef class List__MyEnumA(thrift.py3.types.Container): return False if not isinstance(item, MyEnumA): return False - return std_libcpp.find[vector[cMyEnumA].iterator, cMyEnumA](deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), MyEnumA_to_cpp(item)) != deref(self._cpp_obj).end() + return std_libcpp.find[vector[cMyEnumA].iterator, cMyEnumA](deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), item) != deref(self._cpp_obj).end() def __iter__(self): if not self: @@ -8260,7 +7601,7 @@ cdef class List__MyEnumA(thrift.py3.types.Container): cdef vector[cMyEnumA].iterator loc = std_libcpp.find[vector[cMyEnumA].iterator, cMyEnumA]( std_libcpp.next(deref(self._cpp_obj).begin(), offset_begin), end, - MyEnumA_to_cpp(item) ) + item ) if loc != end: return std_libcpp.distance(deref(self._cpp_obj).begin(), loc) raise err @@ -8271,7 +7612,7 @@ cdef class List__MyEnumA(thrift.py3.types.Container): if not isinstance(item, MyEnumA): return 0 return std_libcpp.count[vector[cMyEnumA].iterator, cMyEnumA]( - deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), MyEnumA_to_cpp(item)) + deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), item) def __reduce__(self): return (List__MyEnumA, (list(self), )) @@ -11581,7 +10922,7 @@ cdef class Map__MyEnumA_string(thrift.py3.types.Container): if not isinstance(item, str): raise TypeError(f"{item!r} is not of type str") - deref(c_inst)[MyEnumA_to_cpp(key)] = item.encode('UTF-8') + deref(c_inst)[key] = item.encode('UTF-8') return c_inst def __getitem__(self, key): @@ -11591,7 +10932,7 @@ cdef class Map__MyEnumA_string(thrift.py3.types.Container): if not isinstance(key, MyEnumA): raise err from None cdef cmap[cMyEnumA,string].iterator iter = deref( - self._cpp_obj).find(MyEnumA_to_cpp(key)) + self._cpp_obj).find(key) if iter == deref(self._cpp_obj).end(): raise err cdef string citem = deref(iter).second @@ -11642,7 +10983,7 @@ cdef class Map__MyEnumA_string(thrift.py3.types.Container): return False if not isinstance(key, MyEnumA): return False - cdef cMyEnumA ckey = MyEnumA_to_cpp(key) + cdef cMyEnumA ckey = key return deref(self._cpp_obj).count(ckey) > 0 def get(self, key, default=None): diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/extend/types.h b/thrift/compiler/test/fixtures/namespace/gen-py3/extend/types.h new file mode 100644 index 00000000000..ebe371f63b5 --- /dev/null +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/extend/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/extend_types.h" diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.h b/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.h new file mode 100644 index 00000000000..24a161623b7 --- /dev/null +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "gen-cpp2/hsmodule_types.h" diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.pxd b/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.pxd index b41b07ece65..1c685a8fcea 100644 --- a/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.pxd +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "gen-py3/hsmodule/types.h": + pass diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.pyx b/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.pyx index 01cca5bc89e..db3b387aa22 100644 --- a/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.pyx +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/hsmodule/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,13 +37,13 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport hsmodule.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class HsFoo(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/module/types.h b/thrift/compiler/test/fixtures/namespace/gen-py3/module/types.h new file mode 100644 index 00000000000..af78922d032 --- /dev/null +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/module/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.h b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.h new file mode 100644 index 00000000000..ebe371f63b5 --- /dev/null +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/extend_types.h" diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.pxd b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.pxd index 32118bb2f4d..9eb028be941 100644 --- a/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.pxd +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.pxd @@ -27,6 +27,8 @@ from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional cimport hsmodule.types as _hsmodule_types +cdef extern from "src/gen-py3/extend/types.h": + pass diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.pyx b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.pyx index ef02887f211..95e858b2551 100644 --- a/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.pyx +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/extend/test/extend/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport hsmodule.types as _hsmodule_types @@ -41,3 +45,4 @@ import hsmodule.types as _hsmodule_types cimport my.namespacing.extend.test.extend.types_reflection as _types_reflection + diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.h b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.h new file mode 100644 index 00000000000..af78922d032 --- /dev/null +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.pxd b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.pxd index 351672aac56..d84216f4791 100644 --- a/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.pxd +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.pyx b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.pyx index 8e2e1292228..08b5e016a72 100644 --- a/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.pyx +++ b/thrift/compiler/test/fixtures/namespace/gen-py3/my/namespacing/test/module/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,13 +37,13 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport my.namespacing.test.module.module.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class Foo(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.h b/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.h new file mode 100644 index 00000000000..caea6e80997 --- /dev/null +++ b/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.h @@ -0,0 +1,22 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::Animal>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + diff --git a/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.pxd index 5f3d970381b..a0020c1e64b 100644 --- a/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.pxd @@ -26,15 +26,14 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef cppclass cAnimal "::cpp2::Animal": - bint operator==(cAnimal&) - bint operator!=(cAnimal&) - cAnimal Animal__DOG "::cpp2::Animal::DOG" - cAnimal Animal__CAT "::cpp2::Animal::CAT" - cAnimal Animal__TARANTULA "::cpp2::Animal::TARANTULA" + pass + @@ -42,11 +41,6 @@ cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef class Animal(thrift.py3.types.CompiledEnum): pass - -cdef cAnimal Animal_to_cpp(Animal value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::cpp2": cdef cppclass cColor__isset "::cpp2::Color::__isset": bint red diff --git a/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.pyx index 596a597ade9..6da1240d227 100644 --- a/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/optionals/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,118 +37,43 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection -cdef object __AnimalEnumInstances = None # Set[Animal] -cdef object __AnimalEnumMembers = {} # Dict[str, Animal] -cdef object __AnimalEnumUniqueValues = dict() # Dict[int, Animal] + +cdef __EnumData __Animal_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cAnimal](), Animal) + @__cython.internal @__cython.auto_pickle(False) -cdef class __AnimalMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 1: - return Animal.DOG - elif cvalue == 2: - return Animal.CAT - elif cvalue == 3: - return Animal.TARANTULA - - raise ValueError(f'{value} is not a valid Animal') - - def __getitem__(cls, name): - return __AnimalEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'DOG', - 'CAT', - 'TARANTULA', - ] - - def __iter__(cls): - return iter(__AnimalEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __AnimalEnumInstances +cdef class __AnimalMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__AnimalEnumInstances) + def __get_by_name(cls, str name): + return __Animal_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __Animal_enum_data.get_by_value(value) -cdef __Animal_unique_instance(int value, str name): - inst = __AnimalEnumUniqueValues.get(value) - if inst is None: - inst = __AnimalEnumUniqueValues[value] = Animal.__new__(Animal, value, name) - __AnimalEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __Animal_enum_data.get_all_names() + + def __len__(cls): + return __Animal_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class Animal(thrift.py3.types.CompiledEnum): - DOG = __Animal_unique_instance(1, "DOG") - CAT = __Animal_unique_instance(2, "CAT") - TARANTULA = __Animal_unique_instance(3, "TARANTULA") - __members__ = thrift.py3.types.MappingProxyType(__AnimalEnumMembers) - - def __cinit__(self, value, name): - if __AnimalEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"Animal.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str + cdef get_by_name(self, str name): + return __Animal_enum_data.get_by_name(name) - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, Animal): - warnings.warn(f"comparison not supported between instances of { Animal } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return Animal, (self.value,) __SetMetaClass( Animal, __AnimalMeta) -__AnimalEnumInstances = set(__AnimalEnumUniqueValues.values()) -cdef inline cAnimal Animal_to_cpp(Animal value): - cdef int cvalue = value.value - if cvalue == 1: - return Animal__DOG - elif cvalue == 2: - return Animal__CAT - elif cvalue == 3: - return Animal__TARANTULA @__cython.auto_pickle(False) cdef class Color(thrift.py3.types.Struct): @@ -1027,7 +957,7 @@ cdef class Person(thrift.py3.types.Struct): deref(c_inst).petNames_ref().assign(deref(Map__Animal_string(petNames)._cpp_obj)) deref(c_inst).__isset.petNames = True if afraidOfAnimal is not None: - deref(c_inst).afraidOfAnimal_ref().assign(Animal_to_cpp(afraidOfAnimal)) + deref(c_inst).afraidOfAnimal_ref().assign(afraidOfAnimal) deref(c_inst).__isset.afraidOfAnimal = True if vehicles is not None: deref(c_inst).vehicles_ref().assign(deref(List__Vehicle(vehicles)._cpp_obj)) @@ -1522,7 +1452,7 @@ cdef class Map__Animal_string(thrift.py3.types.Container): if not isinstance(item, str): raise TypeError(f"{item!r} is not of type str") - deref(c_inst)[Animal_to_cpp(key)] = item.encode('UTF-8') + deref(c_inst)[key] = item.encode('UTF-8') return c_inst def __getitem__(self, key): @@ -1532,7 +1462,7 @@ cdef class Map__Animal_string(thrift.py3.types.Container): if not isinstance(key, Animal): raise err from None cdef cmap[cAnimal,string].iterator iter = deref( - self._cpp_obj).find(Animal_to_cpp(key)) + self._cpp_obj).find(key) if iter == deref(self._cpp_obj).end(): raise err cdef string citem = deref(iter).second @@ -1583,7 +1513,7 @@ cdef class Map__Animal_string(thrift.py3.types.Container): return False if not isinstance(key, Animal): return False - cdef cAnimal ckey = Animal_to_cpp(key) + cdef cAnimal ckey = key return deref(self._cpp_obj).count(ckey) > 0 def get(self, key, default=None): diff --git a/thrift/compiler/test/fixtures/params/gen-py3/module/types.h b/thrift/compiler/test/fixtures/params/gen-py3/module/types.h new file mode 100644 index 00000000000..af78922d032 --- /dev/null +++ b/thrift/compiler/test/fixtures/params/gen-py3/module/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" diff --git a/thrift/compiler/test/fixtures/params/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/params/gen-py3/module/types.pxd index 087a88f98ee..e6305e45907 100644 --- a/thrift/compiler/test/fixtures/params/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/params/gen-py3/module/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/params/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/params/gen-py3/module/types.pyx index 05dcd1704c2..5042f6e07f0 100644 --- a/thrift/compiler/test/fixtures/params/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/params/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,13 +37,13 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class List__i32(thrift.py3.types.Container): def __init__(self, items=None): diff --git a/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.h b/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.h new file mode 100644 index 00000000000..cccf38f47ee --- /dev/null +++ b/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/empty_types.h" diff --git a/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.pxd b/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.pxd index 289d905297b..855f18aa91b 100644 --- a/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.pxd +++ b/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/empty/types.h": + pass diff --git a/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.pyx b/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.pyx index 34ce92173a6..1ae30d96ef7 100644 --- a/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.pyx +++ b/thrift/compiler/test/fixtures/py3/gen-py3/empty/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,10 +37,10 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport empty.types_reflection as _types_reflection + diff --git a/thrift/compiler/test/fixtures/py3/gen-py3/module/clients.pyx b/thrift/compiler/test/fixtures/py3/gen-py3/module/clients.pyx index 6ef9eff2650..036f964b846 100644 --- a/thrift/compiler/test/fixtures/py3/gen-py3/module/clients.pyx +++ b/thrift/compiler/test/fixtures/py3/gen-py3/module/clients.pyx @@ -1306,7 +1306,7 @@ cdef class SimpleService(thrift.py3.client.Client): bridgeFutureWith[_module_types.cAnEnum]( self._executor, down_cast_ptr[cSimpleServiceClientWrapper, cClientWrapper](self._client.get()).set_enum(rpc_options._cpp_obj, - _module_types.AnEnum_to_cpp(in_enum), + <_module_types.cAnEnum>in_enum, ), SimpleService_set_enum_callback, __userdata diff --git a/thrift/compiler/test/fixtures/py3/gen-py3/module/services.pyx b/thrift/compiler/test/fixtures/py3/gen-py3/module/services.pyx index cd2d1a09e91..19706278cd7 100644 --- a/thrift/compiler/test/fixtures/py3/gen-py3/module/services.pyx +++ b/thrift/compiler/test/fixtures/py3/gen-py3/module/services.pyx @@ -2260,7 +2260,7 @@ async def SimpleService_set_enum_coro( cTApplicationExceptionType__UNKNOWN, repr(ex).encode('UTF-8') )) else: - promise.cPromise.setValue(_module_types.AnEnum_to_cpp(result)) + promise.cPromise.setValue(<_module_types.cAnEnum>result) cdef api void call_cy_SimpleService_list_of_lists( object self, diff --git a/thrift/compiler/test/fixtures/py3/gen-py3/module/types.h b/thrift/compiler/test/fixtures/py3/gen-py3/module/types.h new file mode 100644 index 00000000000..1ff5d811db1 --- /dev/null +++ b/thrift/compiler/test/fixtures/py3/gen-py3/module/types.h @@ -0,0 +1,44 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::py3::simple::AnEnum>::namesmap() { + static const folly::Indestructible pairs { + { + {"NOTSET", "None"}, + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::py3::simple::Flags>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::py3::simple::BinaryUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} diff --git a/thrift/compiler/test/fixtures/py3/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/py3/gen-py3/module/types.pxd index 65d3c86e3dc..63d8f0f7ec0 100644 --- a/thrift/compiler/test/fixtures/py3/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/py3/gen-py3/module/types.pxd @@ -26,26 +26,19 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from *: ctypedef bstring foo_Bar "foo::Bar" cdef extern from "src/gen-cpp2/module_types.h" namespace "::py3::simple": cdef cppclass cAnEnum "::py3::simple::AnEnum": - bint operator==(cAnEnum&) - bint operator!=(cAnEnum&) - cAnEnum AnEnum__NOTSET "::py3::simple::AnEnum::None" - cAnEnum AnEnum__ONE "::py3::simple::AnEnum::ONE" - cAnEnum AnEnum__TWO "::py3::simple::AnEnum::TWO" - cAnEnum AnEnum__THREE "::py3::simple::AnEnum::THREE" - cAnEnum AnEnum__FOUR "::py3::simple::AnEnum::FOUR" + pass + cdef cppclass cFlags "::py3::simple::Flags": - bint operator==(cFlags&) - bint operator!=(cFlags&) - cFlags Flags__flag_A "::py3::simple::Flags::flag_A" - cFlags Flags__flag_B "::py3::simple::Flags::flag_B" - cFlags Flags__flag_C "::py3::simple::Flags::flag_C" - cFlags Flags__flag_D "::py3::simple::Flags::flag_D" + pass + @@ -54,19 +47,9 @@ cdef class AnEnum(thrift.py3.types.CompiledEnum): pass -cdef cAnEnum AnEnum_to_cpp(AnEnum value) - - - - cdef class Flags(thrift.py3.types.Flag): pass - -cdef cFlags Flags_to_cpp(Flags value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::py3::simple": cdef cppclass cSimpleException__isset "::py3::simple::SimpleException::__isset": bint err_code diff --git a/thrift/compiler/test/fixtures/py3/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/py3/gen-py3/module/types.pyx index 06dcf755982..3d6545de7f8 100644 --- a/thrift/compiler/test/fixtures/py3/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/py3/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,384 +37,109 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection -cdef object __AnEnumEnumInstances = None # Set[AnEnum] -cdef object __AnEnumEnumMembers = {} # Dict[str, AnEnum] -cdef object __AnEnumEnumUniqueValues = dict() # Dict[int, AnEnum] + +cdef __EnumData __AnEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cAnEnum](), AnEnum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __AnEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return AnEnum.NOTSET - elif cvalue == 1: - return AnEnum.ONE - elif cvalue == 2: - return AnEnum.TWO - elif cvalue == 3: - return AnEnum.THREE - elif cvalue == 4: - return AnEnum.FOUR - - raise ValueError(f'{value} is not a valid AnEnum') - - def __getitem__(cls, name): - return __AnEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'NOTSET', - 'ONE', - 'TWO', - 'THREE', - 'FOUR', - ] - - def __iter__(cls): - return iter(__AnEnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __AnEnumEnumInstances +cdef class __AnEnumMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__AnEnumEnumInstances) + def __get_by_name(cls, str name): + return __AnEnum_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __AnEnum_enum_data.get_by_value(value) -cdef __AnEnum_unique_instance(int value, str name): - inst = __AnEnumEnumUniqueValues.get(value) - if inst is None: - inst = __AnEnumEnumUniqueValues[value] = AnEnum.__new__(AnEnum, value, name) - __AnEnumEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __AnEnum_enum_data.get_all_names() + + def __len__(cls): + return __AnEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class AnEnum(thrift.py3.types.CompiledEnum): - NOTSET = __AnEnum_unique_instance(0, "NOTSET") - ONE = __AnEnum_unique_instance(1, "ONE") - TWO = __AnEnum_unique_instance(2, "TWO") - THREE = __AnEnum_unique_instance(3, "THREE") - FOUR = __AnEnum_unique_instance(4, "FOUR") - __members__ = thrift.py3.types.MappingProxyType(__AnEnumEnumMembers) - - def __cinit__(self, value, name): - if __AnEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"AnEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr + cdef get_by_name(self, str name): + return __AnEnum_enum_data.get_by_name(name) - def __str__(self): - return self.__str - def __int__(self): - return self.value - def __eq__(self, other): - if not isinstance(other, AnEnum): - warnings.warn(f"comparison not supported between instances of { AnEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash +__SetMetaClass( AnEnum, __AnEnumMeta) - def __reduce__(self): - return AnEnum, (self.value,) +cdef __EnumFlagsData __Flags_enum_data = __EnumFlagsData.create(thrift.py3.types.createEnumFlagsData[cFlags](), Flags) -__SetMetaClass( AnEnum, __AnEnumMeta) -__AnEnumEnumInstances = set(__AnEnumEnumUniqueValues.values()) - - -cdef inline cAnEnum AnEnum_to_cpp(AnEnum value): - cdef int cvalue = value.value - if cvalue == 0: - return AnEnum__NOTSET - elif cvalue == 1: - return AnEnum__ONE - elif cvalue == 2: - return AnEnum__TWO - elif cvalue == 3: - return AnEnum__THREE - elif cvalue == 4: - return AnEnum__FOUR -cdef object __FlagsEnumInstances = None # Set[Flags] -cdef object __FlagsEnumMembers = {} # Dict[str, Flags] -cdef object __FlagsEnumUniqueValues = dict() # Dict[int, Flags] -cdef object __FlagsEnumValueMapping = None # WeakMapping[Int, Flags] @__cython.internal @__cython.auto_pickle(False) -cdef class __FlagsMeta(type): - def __call__(cls, value): - cdef int cvalue - cdef bint invert = False - if isinstance(value, cls): - return value - if isinstance(value, int): - if value < 0: - invert = True - value = ~value - cvalue = value - if cvalue == 1: - return ~Flags.flag_A if invert else Flags.flag_A - elif cvalue == 2: - return ~Flags.flag_B if invert else Flags.flag_B - elif cvalue == 4: - return ~Flags.flag_C if invert else Flags.flag_C - elif cvalue == 8: - return ~Flags.flag_D if invert else Flags.flag_D - item = __FlagsEnumValueMapping.get(value, None) - if item is None: - item = Flags.__new__(Flags, value, None) - return ~item if invert else item - - raise ValueError(f'{value} is not a valid Flags') - - def __getitem__(cls, name): - return __FlagsEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'flag_A', - 'flag_B', - 'flag_C', - 'flag_D', - ] - - def __iter__(cls): - return iter(__FlagsEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __FlagsEnumInstances +cdef class __FlagsMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__FlagsEnumInstances) + def __get_by_name(cls, str name): + return __Flags_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __Flags_enum_data.get_by_value(value) -cdef __Flags_unique_instance(int value, str name): - inst = __FlagsEnumUniqueValues.get(value) - if inst is None: - inst = __FlagsEnumUniqueValues[value] = Flags.__new__(Flags, value, name) - __FlagsEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __Flags_enum_data.get_all_names() + + def __len__(cls): + return __Flags_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class Flags(thrift.py3.types.Flag): - flag_A = __Flags_unique_instance(1, "flag_A") - flag_B = __Flags_unique_instance(2, "flag_B") - flag_C = __Flags_unique_instance(4, "flag_C") - flag_D = __Flags_unique_instance(8, "flag_D") - __members__ = thrift.py3.types.MappingProxyType(__FlagsEnumMembers) - - def __cinit__(self, value, name): - __ExistingValues = __FlagsEnumValueMapping - cdef int temp - if __ExistingValues is not None: - if value < 0 or value in __ExistingValues: - raise TypeError('__new__ is disabled in the interest of type-safety') - elif value == 0: - name = "0" - else: - combo = [] - temp = value - while temp: - flag = thrift.py3.types.largest_flag(temp) - if flag not in __ExistingValues: - raise ValueError(f'{value} is not a valid Flags') - combo.append(__ExistingValues[flag].name) - temp ^= flag - name = '|'.join(combo) - __ExistingValues[value] = self - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"Flags.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str + cdef get_by_name(self, str name): + return __Flags_enum_data.get_by_name(name) - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, Flags): - warnings.warn(f"comparison not supported between instances of { Flags } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return Flags, (self.value,) - - def __contains__(self, other): - if not isinstance(other, Flags): - return NotImplemented - return other.value & self.value == other.value - - def __bool__(self): - return bool(self.value) - - def __or__(self, other): - if not isinstance(other, Flags): - return NotImplemented - return Flags(self.value | other.value) - - def __and__(self, other): - if not isinstance(other, Flags): - return NotImplemented - return Flags(self.value & other.value) - - def __xor__(self, other): - if not isinstance(other, Flags): - return NotImplemented - return Flags(self.value ^ other.value) def __invert__(self): - inverted = Flags(0) - for m in Flags: - if not (m.value & self.value): - inverted = inverted | m - return Flags(inverted) + return __Flags_enum_data.get_invert(self.value) __SetMetaClass( Flags, __FlagsMeta) -__FlagsEnumInstances = set(__FlagsEnumUniqueValues.values()) -__FlagsEnumValueMapping = __weakref.WeakValueDictionary( - {f.value: f for f in tuple(Flags)} -) - -cdef inline cFlags Flags_to_cpp(Flags value): - return (value.value) -cdef object __BinaryUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __BinaryUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cBinaryUnion](), + __BinaryUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __BinaryUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __BinaryUnion_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __BinaryUnionType.EMPTY - elif cvalue == 1: - return __BinaryUnionType.iobuf_val - - raise ValueError(f'{value} is not a valid BinaryUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __BinaryUnionType.EMPTY - elif name == "iobuf_val": - return __BinaryUnionType.iobuf_val - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'iobuf_val', - ] - - @property - def __members__(cls): - return {m.name: m for m in cls} +cdef class __BinaryUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - def __iter__(cls): - yield __BinaryUnionType.EMPTY - yield __BinaryUnionType.iobuf_val + def __get_by_name(cls, str name): + return __BinaryUnion_union_type_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __BinaryUnion_union_type_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __BinaryUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __BinaryUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 1+1 # For Empty + return __BinaryUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __BinaryUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __BinaryUnionType.__new__(__BinaryUnionType, 0, "EMPTY") - iobuf_val = __BinaryUnionType.__new__(__BinaryUnionType, 1, "iobuf_val") - - def __cinit__(self, value, name): - if __BinaryUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"BinaryUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __BinaryUnionType): - warnings.warn(f"comparison not supported between instances of { __BinaryUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other + cdef get_by_name(self, str name): + return __BinaryUnion_union_type_enum_data.get_by_name(name) - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __BinaryUnionType, (self.value,) __SetMetaClass( __BinaryUnionType, __BinaryUnion_Union_TypeMeta) -__BinaryUnion_Union_TypeEnumMembers = set(__BinaryUnionType) @__cython.auto_pickle(False) @@ -1363,7 +1093,7 @@ cdef class ComplexStruct(thrift.py3.types.Struct): deref(c_inst).name_ref().assign(thrift.py3.types.move(thrift.py3.types.bytes_to_string(name.encode('utf-8')))) deref(c_inst).__isset.name = True if an_enum is not None: - deref(c_inst).an_enum_ref().assign(AnEnum_to_cpp(an_enum)) + deref(c_inst).an_enum_ref().assign(an_enum) deref(c_inst).__isset.an_enum = True if some_bytes is not None: deref(c_inst).some_bytes_ref().assign(thrift.py3.types.move(thrift.py3.types.bytes_to_string(some_bytes))) @@ -5399,7 +5129,7 @@ cdef class List__AnEnum(thrift.py3.types.Container): for item in items: if not isinstance(item, AnEnum): raise TypeError(f"{item!r} is not of type AnEnum") - deref(c_inst).push_back(AnEnum_to_cpp(item)) + deref(c_inst).push_back(item) return c_inst def __add__(object self, object other): @@ -5458,7 +5188,7 @@ cdef class List__AnEnum(thrift.py3.types.Container): return False if not isinstance(item, AnEnum): return False - return std_libcpp.find[vector[cAnEnum].iterator, cAnEnum](deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), AnEnum_to_cpp(item)) != deref(self._cpp_obj).end() + return std_libcpp.find[vector[cAnEnum].iterator, cAnEnum](deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), item) != deref(self._cpp_obj).end() def __iter__(self): if not self: @@ -5514,7 +5244,7 @@ cdef class List__AnEnum(thrift.py3.types.Container): cdef vector[cAnEnum].iterator loc = std_libcpp.find[vector[cAnEnum].iterator, cAnEnum]( std_libcpp.next(deref(self._cpp_obj).begin(), offset_begin), end, - AnEnum_to_cpp(item) ) + item ) if loc != end: return std_libcpp.distance(deref(self._cpp_obj).begin(), loc) raise err @@ -5525,7 +5255,7 @@ cdef class List__AnEnum(thrift.py3.types.Container): if not isinstance(item, AnEnum): return 0 return std_libcpp.count[vector[cAnEnum].iterator, cAnEnum]( - deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), AnEnum_to_cpp(item)) + deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), item) def __reduce__(self): return (List__AnEnum, (list(self), )) diff --git a/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.h b/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.h new file mode 100644 index 00000000000..fdc2dfe69f6 --- /dev/null +++ b/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.h @@ -0,0 +1,22 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "gen-cpp2/module0_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::module0::Enum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + diff --git a/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.pxd b/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.pxd index 6fd91551c2e..768bed488fa 100644 --- a/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.pxd +++ b/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.pxd @@ -26,15 +26,14 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "gen-py3/module0/types.h": + pass cdef extern from "gen-cpp2/module0_types.h" namespace "::module0": cdef cppclass cEnum "::module0::Enum": - bint operator==(cEnum&) - bint operator!=(cEnum&) - cEnum Enum__ONE "::module0::Enum::ONE" - cEnum Enum__TWO "::module0::Enum::TWO" - cEnum Enum__THREE "::module0::Enum::THREE" + pass + @@ -42,11 +41,6 @@ cdef extern from "gen-cpp2/module0_types.h" namespace "::module0": cdef class Enum(thrift.py3.types.CompiledEnum): pass - -cdef cEnum Enum_to_cpp(Enum value) - - - cdef extern from "gen-cpp2/module0_types_custom_protocol.h" namespace "::module0": cdef cppclass cStruct__isset "::module0::Struct::__isset": bint first diff --git a/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.pyx b/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.pyx index c4dc17ede8c..99e42c73899 100644 --- a/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.pyx +++ b/thrift/compiler/test/fixtures/qualified/gen-py3/module0/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,118 +37,43 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module0.types_reflection as _types_reflection -cdef object __EnumEnumInstances = None # Set[Enum] -cdef object __EnumEnumMembers = {} # Dict[str, Enum] -cdef object __EnumEnumUniqueValues = dict() # Dict[int, Enum] + +cdef __EnumData __Enum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cEnum](), Enum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __EnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 1: - return Enum.ONE - elif cvalue == 2: - return Enum.TWO - elif cvalue == 3: - return Enum.THREE - - raise ValueError(f'{value} is not a valid Enum') - - def __getitem__(cls, name): - return __EnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'ONE', - 'TWO', - 'THREE', - ] - - def __iter__(cls): - return iter(__EnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __EnumEnumInstances +cdef class __EnumMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__EnumEnumInstances) + def __get_by_name(cls, str name): + return __Enum_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __Enum_enum_data.get_by_value(value) -cdef __Enum_unique_instance(int value, str name): - inst = __EnumEnumUniqueValues.get(value) - if inst is None: - inst = __EnumEnumUniqueValues[value] = Enum.__new__(Enum, value, name) - __EnumEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __Enum_enum_data.get_all_names() + + def __len__(cls): + return __Enum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class Enum(thrift.py3.types.CompiledEnum): - ONE = __Enum_unique_instance(1, "ONE") - TWO = __Enum_unique_instance(2, "TWO") - THREE = __Enum_unique_instance(3, "THREE") - __members__ = thrift.py3.types.MappingProxyType(__EnumEnumMembers) - - def __cinit__(self, value, name): - if __EnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"Enum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str + cdef get_by_name(self, str name): + return __Enum_enum_data.get_by_name(name) - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, Enum): - warnings.warn(f"comparison not supported between instances of { Enum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return Enum, (self.value,) __SetMetaClass( Enum, __EnumMeta) -__EnumEnumInstances = set(__EnumEnumUniqueValues.values()) -cdef inline cEnum Enum_to_cpp(Enum value): - cdef int cvalue = value.value - if cvalue == 1: - return Enum__ONE - elif cvalue == 2: - return Enum__TWO - elif cvalue == 3: - return Enum__THREE @__cython.auto_pickle(False) cdef class Struct(thrift.py3.types.Struct): @@ -391,7 +321,7 @@ cdef class List__Enum(thrift.py3.types.Container): for item in items: if not isinstance(item, Enum): raise TypeError(f"{item!r} is not of type Enum") - deref(c_inst).push_back(Enum_to_cpp(item)) + deref(c_inst).push_back(item) return c_inst def __add__(object self, object other): @@ -450,7 +380,7 @@ cdef class List__Enum(thrift.py3.types.Container): return False if not isinstance(item, Enum): return False - return std_libcpp.find[vector[cEnum].iterator, cEnum](deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), Enum_to_cpp(item)) != deref(self._cpp_obj).end() + return std_libcpp.find[vector[cEnum].iterator, cEnum](deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), item) != deref(self._cpp_obj).end() def __iter__(self): if not self: @@ -506,7 +436,7 @@ cdef class List__Enum(thrift.py3.types.Container): cdef vector[cEnum].iterator loc = std_libcpp.find[vector[cEnum].iterator, cEnum]( std_libcpp.next(deref(self._cpp_obj).begin(), offset_begin), end, - Enum_to_cpp(item) ) + item ) if loc != end: return std_libcpp.distance(deref(self._cpp_obj).begin(), loc) raise err @@ -517,7 +447,7 @@ cdef class List__Enum(thrift.py3.types.Container): if not isinstance(item, Enum): return 0 return std_libcpp.count[vector[cEnum].iterator, cEnum]( - deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), Enum_to_cpp(item)) + deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), item) def __reduce__(self): return (List__Enum, (list(self), )) diff --git a/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.h b/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.h new file mode 100644 index 00000000000..1ef86284e66 --- /dev/null +++ b/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.h @@ -0,0 +1,22 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "gen-cpp2/module1_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::module1::Enum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + diff --git a/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.pxd b/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.pxd index 7eac48432ea..88e63f5e33f 100644 --- a/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.pxd +++ b/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.pxd @@ -26,15 +26,14 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "gen-py3/module1/types.h": + pass cdef extern from "gen-cpp2/module1_types.h" namespace "::module1": cdef cppclass cEnum "::module1::Enum": - bint operator==(cEnum&) - bint operator!=(cEnum&) - cEnum Enum__ONE "::module1::Enum::ONE" - cEnum Enum__TWO "::module1::Enum::TWO" - cEnum Enum__THREE "::module1::Enum::THREE" + pass + @@ -42,11 +41,6 @@ cdef extern from "gen-cpp2/module1_types.h" namespace "::module1": cdef class Enum(thrift.py3.types.CompiledEnum): pass - -cdef cEnum Enum_to_cpp(Enum value) - - - cdef extern from "gen-cpp2/module1_types_custom_protocol.h" namespace "::module1": cdef cppclass cStruct__isset "::module1::Struct::__isset": bint first diff --git a/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.pyx b/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.pyx index 3f1df1f2ea1..90b6aee1f35 100644 --- a/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.pyx +++ b/thrift/compiler/test/fixtures/qualified/gen-py3/module1/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,118 +37,43 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module1.types_reflection as _types_reflection -cdef object __EnumEnumInstances = None # Set[Enum] -cdef object __EnumEnumMembers = {} # Dict[str, Enum] -cdef object __EnumEnumUniqueValues = dict() # Dict[int, Enum] + +cdef __EnumData __Enum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cEnum](), Enum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __EnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 1: - return Enum.ONE - elif cvalue == 2: - return Enum.TWO - elif cvalue == 3: - return Enum.THREE - - raise ValueError(f'{value} is not a valid Enum') - - def __getitem__(cls, name): - return __EnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'ONE', - 'TWO', - 'THREE', - ] - - def __iter__(cls): - return iter(__EnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __EnumEnumInstances +cdef class __EnumMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__EnumEnumInstances) + def __get_by_name(cls, str name): + return __Enum_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __Enum_enum_data.get_by_value(value) -cdef __Enum_unique_instance(int value, str name): - inst = __EnumEnumUniqueValues.get(value) - if inst is None: - inst = __EnumEnumUniqueValues[value] = Enum.__new__(Enum, value, name) - __EnumEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __Enum_enum_data.get_all_names() + + def __len__(cls): + return __Enum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class Enum(thrift.py3.types.CompiledEnum): - ONE = __Enum_unique_instance(1, "ONE") - TWO = __Enum_unique_instance(2, "TWO") - THREE = __Enum_unique_instance(3, "THREE") - __members__ = thrift.py3.types.MappingProxyType(__EnumEnumMembers) - - def __cinit__(self, value, name): - if __EnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"Enum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str + cdef get_by_name(self, str name): + return __Enum_enum_data.get_by_name(name) - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, Enum): - warnings.warn(f"comparison not supported between instances of { Enum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return Enum, (self.value,) __SetMetaClass( Enum, __EnumMeta) -__EnumEnumInstances = set(__EnumEnumUniqueValues.values()) -cdef inline cEnum Enum_to_cpp(Enum value): - cdef int cvalue = value.value - if cvalue == 1: - return Enum__ONE - elif cvalue == 2: - return Enum__TWO - elif cvalue == 3: - return Enum__THREE @__cython.auto_pickle(False) cdef class Struct(thrift.py3.types.Struct): @@ -391,7 +321,7 @@ cdef class List__Enum(thrift.py3.types.Container): for item in items: if not isinstance(item, Enum): raise TypeError(f"{item!r} is not of type Enum") - deref(c_inst).push_back(Enum_to_cpp(item)) + deref(c_inst).push_back(item) return c_inst def __add__(object self, object other): @@ -450,7 +380,7 @@ cdef class List__Enum(thrift.py3.types.Container): return False if not isinstance(item, Enum): return False - return std_libcpp.find[vector[cEnum].iterator, cEnum](deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), Enum_to_cpp(item)) != deref(self._cpp_obj).end() + return std_libcpp.find[vector[cEnum].iterator, cEnum](deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), item) != deref(self._cpp_obj).end() def __iter__(self): if not self: @@ -506,7 +436,7 @@ cdef class List__Enum(thrift.py3.types.Container): cdef vector[cEnum].iterator loc = std_libcpp.find[vector[cEnum].iterator, cEnum]( std_libcpp.next(deref(self._cpp_obj).begin(), offset_begin), end, - Enum_to_cpp(item) ) + item ) if loc != end: return std_libcpp.distance(deref(self._cpp_obj).begin(), loc) raise err @@ -517,7 +447,7 @@ cdef class List__Enum(thrift.py3.types.Container): if not isinstance(item, Enum): return 0 return std_libcpp.count[vector[cEnum].iterator, cEnum]( - deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), Enum_to_cpp(item)) + deref(self._cpp_obj).begin(), deref(self._cpp_obj).end(), item) def __reduce__(self): return (List__Enum, (list(self), )) diff --git a/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.h b/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.h new file mode 100644 index 00000000000..f6279092761 --- /dev/null +++ b/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module2_types.h" diff --git a/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.pxd b/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.pxd index 344becdfb3d..6a1cea4233e 100644 --- a/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.pxd +++ b/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.pxd @@ -28,6 +28,8 @@ from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_f from folly.optional cimport cOptional cimport module0.types as _module0_types cimport module1.types as _module1_types +cdef extern from "src/gen-py3/module2/types.h": + pass diff --git a/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.pyx b/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.pyx index 351b331b678..6f3589902f1 100644 --- a/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.pyx +++ b/thrift/compiler/test/fixtures/qualified/gen-py3/module2/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module0.types as _module0_types @@ -43,6 +47,7 @@ import module1.types as _module1_types cimport module2.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class Struct(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/refs/gen-py3/module/types.h b/thrift/compiler/test/fixtures/refs/gen-py3/module/types.h new file mode 100644 index 00000000000..be1cf3122c2 --- /dev/null +++ b/thrift/compiler/test/fixtures/refs/gen-py3/module/types.h @@ -0,0 +1,32 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::TypedEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::MyUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} diff --git a/thrift/compiler/test/fixtures/refs/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/refs/gen-py3/module/types.pxd index 2b940532b1a..51e112d3640 100644 --- a/thrift/compiler/test/fixtures/refs/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/refs/gen-py3/module/types.pxd @@ -26,14 +26,14 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef cppclass cTypedEnum "::cpp2::TypedEnum": - bint operator==(cTypedEnum&) - bint operator!=(cTypedEnum&) - cTypedEnum TypedEnum__VAL1 "::cpp2::TypedEnum::VAL1" - cTypedEnum TypedEnum__VAL2 "::cpp2::TypedEnum::VAL2" + pass + @@ -41,11 +41,6 @@ cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef class TypedEnum(thrift.py3.types.CompiledEnum): pass - -cdef cTypedEnum TypedEnum_to_cpp(TypedEnum value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::cpp2": cdef enum cMyUnion__type "::cpp2::MyUnion::Type": cMyUnion__type___EMPTY__ "::cpp2::MyUnion::Type::__EMPTY__", diff --git a/thrift/compiler/test/fixtures/refs/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/refs/gen-py3/module/types.pyx index a412a99974c..573ebd7cd9c 100644 --- a/thrift/compiler/test/fixtures/refs/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/refs/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,211 +37,75 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection -cdef object __TypedEnumEnumInstances = None # Set[TypedEnum] -cdef object __TypedEnumEnumMembers = {} # Dict[str, TypedEnum] -cdef object __TypedEnumEnumUniqueValues = dict() # Dict[int, TypedEnum] -@__cython.internal -@__cython.auto_pickle(False) -cdef class __TypedEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return TypedEnum.VAL1 - elif cvalue == 1: - return TypedEnum.VAL2 +cdef __EnumData __TypedEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cTypedEnum](), TypedEnum) - raise ValueError(f'{value} is not a valid TypedEnum') - def __getitem__(cls, name): - return __TypedEnumEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'VAL1', - 'VAL2', - ] +@__cython.internal +@__cython.auto_pickle(False) +cdef class __TypedEnumMeta(thrift.py3.types.EnumMeta): - def __iter__(cls): - return iter(__TypedEnumEnumUniqueValues.values()) + def __get_by_name(cls, str name): + return __TypedEnum_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __TypedEnum_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __TypedEnumEnumInstances + def __get_all_names(cls): + return __TypedEnum_enum_data.get_all_names() def __len__(cls): - return len(__TypedEnumEnumInstances) - - -cdef __TypedEnum_unique_instance(int value, str name): - inst = __TypedEnumEnumUniqueValues.get(value) - if inst is None: - inst = __TypedEnumEnumUniqueValues[value] = TypedEnum.__new__(TypedEnum, value, name) - __TypedEnumEnumMembers[name] = inst - return inst + return __TypedEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class TypedEnum(thrift.py3.types.CompiledEnum): - VAL1 = __TypedEnum_unique_instance(0, "VAL1") - VAL2 = __TypedEnum_unique_instance(1, "VAL2") - __members__ = thrift.py3.types.MappingProxyType(__TypedEnumEnumMembers) - - def __cinit__(self, value, name): - if __TypedEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"TypedEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, TypedEnum): - warnings.warn(f"comparison not supported between instances of { TypedEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash + cdef get_by_name(self, str name): + return __TypedEnum_enum_data.get_by_name(name) - def __reduce__(self): - return TypedEnum, (self.value,) __SetMetaClass( TypedEnum, __TypedEnumMeta) -__TypedEnumEnumInstances = set(__TypedEnumEnumUniqueValues.values()) - -cdef inline cTypedEnum TypedEnum_to_cpp(TypedEnum value): - cdef int cvalue = value.value - if cvalue == 0: - return TypedEnum__VAL1 - elif cvalue == 1: - return TypedEnum__VAL2 -cdef object __MyUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __MyUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cMyUnion](), + __MyUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __MyUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __MyUnion_Union_TypeEnumMembers: - return value - - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __MyUnionType.EMPTY - elif cvalue == 1: - return __MyUnionType.anInteger - elif cvalue == 2: - return __MyUnionType.aString - - raise ValueError(f'{value} is not a valid MyUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __MyUnionType.EMPTY - elif name == "anInteger": - return __MyUnionType.anInteger - elif name == "aString": - return __MyUnionType.aString - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'anInteger', - 'aString', - ] +cdef class __MyUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - @property - def __members__(cls): - return {m.name: m for m in cls} - - def __iter__(cls): - yield __MyUnionType.EMPTY - yield __MyUnionType.anInteger - yield __MyUnionType.aString + def __get_by_name(cls, str name): + return __MyUnion_union_type_enum_data.get_by_name(name) - def __reversed__(cls): - return reversed(iter(cls)) + def __get_by_value(cls, int value): + return __MyUnion_union_type_enum_data.get_by_value(value) - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __MyUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 2+1 # For Empty + return __MyUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __MyUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __MyUnionType.__new__(__MyUnionType, 0, "EMPTY") - anInteger = __MyUnionType.__new__(__MyUnionType, 1, "anInteger") - aString = __MyUnionType.__new__(__MyUnionType, 2, "aString") - - def __cinit__(self, value, name): - if __MyUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr + cdef get_by_name(self, str name): + return __MyUnion_union_type_enum_data.get_by_name(name) - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __MyUnionType): - warnings.warn(f"comparison not supported between instances of { __MyUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __MyUnionType, (self.value,) __SetMetaClass( __MyUnionType, __MyUnion_Union_TypeMeta) -__MyUnion_Union_TypeEnumMembers = set(__MyUnionType) diff --git a/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.h b/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.h new file mode 100644 index 00000000000..af78922d032 --- /dev/null +++ b/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" diff --git a/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.pxd index 4889acd1524..812384a4e1b 100644 --- a/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.pyx index 61f5323dd3f..c3857da0242 100644 --- a/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/req-opt/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,13 +37,13 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class Foo(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/sink/gen-py3/module/types.h b/thrift/compiler/test/fixtures/sink/gen-py3/module/types.h new file mode 100644 index 00000000000..af78922d032 --- /dev/null +++ b/thrift/compiler/test/fixtures/sink/gen-py3/module/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" diff --git a/thrift/compiler/test/fixtures/sink/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/sink/gen-py3/module/types.pxd index 37d7feb6f48..6e53e1cbffe 100644 --- a/thrift/compiler/test/fixtures/sink/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/sink/gen-py3/module/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/sink/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/sink/gen-py3/module/types.pyx index 97e619fcef9..73e1354d42c 100644 --- a/thrift/compiler/test/fixtures/sink/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/sink/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,13 +37,13 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class InitialResponse(thrift.py3.types.Struct): diff --git a/thrift/compiler/test/fixtures/stream/gen-py3/module/types.h b/thrift/compiler/test/fixtures/stream/gen-py3/module/types.h new file mode 100644 index 00000000000..af78922d032 --- /dev/null +++ b/thrift/compiler/test/fixtures/stream/gen-py3/module/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" diff --git a/thrift/compiler/test/fixtures/stream/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/stream/gen-py3/module/types.pxd index 643d32cb2e2..0d873c2871c 100644 --- a/thrift/compiler/test/fixtures/stream/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/stream/gen-py3/module/types.pxd @@ -34,6 +34,8 @@ from thrift.py3.stream cimport ( ServerStream, cServerStream, ResponseAndServerStream ) from thrift.py3.common cimport RpcOptions as __RpcOptions +cdef extern from "src/gen-py3/module/types.h": + pass diff --git a/thrift/compiler/test/fixtures/stream/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/stream/gen-py3/module/types.pyx index 600e928f23a..f4ea9f25aea 100644 --- a/thrift/compiler/test/fixtures/stream/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/stream/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins import asyncio @@ -41,6 +45,7 @@ from folly.coro cimport bridgeCoroTaskWith cimport module.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class FooEx(thrift.py3.exceptions.GeneratedError): diff --git a/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.h b/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.h new file mode 100644 index 00000000000..109850e0a72 --- /dev/null +++ b/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.h @@ -0,0 +1,22 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::cpp2::MyEnumA>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + diff --git a/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.pxd index 8b29450c6f9..8faea725b71 100644 --- a/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from *: ctypedef cint64_t Foo "Foo" @@ -36,11 +38,8 @@ cdef extern from *: cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef cppclass cMyEnumA "::cpp2::MyEnumA": - bint operator==(cMyEnumA&) - bint operator!=(cMyEnumA&) - cMyEnumA MyEnumA__fieldA "::cpp2::MyEnumA::fieldA" - cMyEnumA MyEnumA__fieldB "::cpp2::MyEnumA::fieldB" - cMyEnumA MyEnumA__fieldC "::cpp2::MyEnumA::fieldC" + pass + @@ -48,11 +47,6 @@ cdef extern from "src/gen-cpp2/module_types.h" namespace "::cpp2": cdef class MyEnumA(thrift.py3.types.CompiledEnum): pass - -cdef cMyEnumA MyEnumA_to_cpp(MyEnumA value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::cpp2": cdef cppclass cSmallStruct__isset "::cpp2::SmallStruct::__isset": bint small_A diff --git a/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.pyx index 5baed5cba74..5a9466e0c55 100644 --- a/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/templated-deserialize/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,118 +37,43 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport module.types_reflection as _types_reflection -cdef object __MyEnumAEnumInstances = None # Set[MyEnumA] -cdef object __MyEnumAEnumMembers = {} # Dict[str, MyEnumA] -cdef object __MyEnumAEnumUniqueValues = dict() # Dict[int, MyEnumA] + +cdef __EnumData __MyEnumA_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cMyEnumA](), MyEnumA) + @__cython.internal @__cython.auto_pickle(False) -cdef class __MyEnumAMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 1: - return MyEnumA.fieldA - elif cvalue == 2: - return MyEnumA.fieldB - elif cvalue == 4: - return MyEnumA.fieldC - - raise ValueError(f'{value} is not a valid MyEnumA') - - def __getitem__(cls, name): - return __MyEnumAEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'fieldA', - 'fieldB', - 'fieldC', - ] - - def __iter__(cls): - return iter(__MyEnumAEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyEnumAEnumInstances +cdef class __MyEnumAMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__MyEnumAEnumInstances) + def __get_by_name(cls, str name): + return __MyEnumA_enum_data.get_by_name(name) + def __get_by_value(cls, int value): + return __MyEnumA_enum_data.get_by_value(value) -cdef __MyEnumA_unique_instance(int value, str name): - inst = __MyEnumAEnumUniqueValues.get(value) - if inst is None: - inst = __MyEnumAEnumUniqueValues[value] = MyEnumA.__new__(MyEnumA, value, name) - __MyEnumAEnumMembers[name] = inst - return inst + def __get_all_names(cls): + return __MyEnumA_enum_data.get_all_names() + + def __len__(cls): + return __MyEnumA_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class MyEnumA(thrift.py3.types.CompiledEnum): - fieldA = __MyEnumA_unique_instance(1, "fieldA") - fieldB = __MyEnumA_unique_instance(2, "fieldB") - fieldC = __MyEnumA_unique_instance(4, "fieldC") - __members__ = thrift.py3.types.MappingProxyType(__MyEnumAEnumMembers) - - def __cinit__(self, value, name): - if __MyEnumAEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyEnumA.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str + cdef get_by_name(self, str name): + return __MyEnumA_enum_data.get_by_name(name) - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, MyEnumA): - warnings.warn(f"comparison not supported between instances of { MyEnumA } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return MyEnumA, (self.value,) __SetMetaClass( MyEnumA, __MyEnumAMeta) -__MyEnumAEnumInstances = set(__MyEnumAEnumUniqueValues.values()) -cdef inline cMyEnumA MyEnumA_to_cpp(MyEnumA value): - cdef int cvalue = value.value - if cvalue == 1: - return MyEnumA__fieldA - elif cvalue == 2: - return MyEnumA__fieldB - elif cvalue == 4: - return MyEnumA__fieldC @__cython.auto_pickle(False) cdef class SmallStruct(thrift.py3.types.Struct): @@ -860,7 +790,7 @@ cdef class containerStruct(thrift.py3.types.Struct): deref(c_inst).fieldP_ref().assign(deref(List__Baz__i32(fieldP)._cpp_obj)) deref(c_inst).__isset.fieldP = True if fieldQ is not None: - deref(c_inst).fieldQ_ref().assign(MyEnumA_to_cpp(fieldQ)) + deref(c_inst).fieldQ_ref().assign(fieldQ) deref(c_inst).__isset.fieldQ = True if fieldR is not None: deref(c_inst).fieldR = make_unique[cmap[string,cbool]](deref(Map__string_bool(fieldR)._cpp_obj)) diff --git a/thrift/compiler/test/fixtures/types/gen-py3/include/types.h b/thrift/compiler/test/fixtures/types/gen-py3/include/types.h new file mode 100644 index 00000000000..d08e8e1f682 --- /dev/null +++ b/thrift/compiler/test/fixtures/types/gen-py3/include/types.h @@ -0,0 +1,11 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "gen-cpp2/include_types.h" diff --git a/thrift/compiler/test/fixtures/types/gen-py3/include/types.pxd b/thrift/compiler/test/fixtures/types/gen-py3/include/types.pxd index b5593ba2b9d..f969161d669 100644 --- a/thrift/compiler/test/fixtures/types/gen-py3/include/types.pxd +++ b/thrift/compiler/test/fixtures/types/gen-py3/include/types.pxd @@ -26,6 +26,8 @@ cimport thrift.py3.types from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional +cdef extern from "gen-py3/include/types.h": + pass cdef extern from * nogil: cdef cppclass std_unordered_map "std::unordered_map"[T, U]: diff --git a/thrift/compiler/test/fixtures/types/gen-py3/include/types.pyx b/thrift/compiler/test/fixtures/types/gen-py3/include/types.pyx index ccae229e2e4..d53c323e71f 100644 --- a/thrift/compiler/test/fixtures/types/gen-py3/include/types.pyx +++ b/thrift/compiler/test/fixtures/types/gen-py3/include/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,13 +37,13 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport include.types_reflection as _types_reflection + @__cython.auto_pickle(False) cdef class std_unordered_map__Map__i32_string(thrift.py3.types.Container): def __init__(self, items=None): diff --git a/thrift/compiler/test/fixtures/types/gen-py3/module/types.h b/thrift/compiler/test/fixtures/types/gen-py3/module/types.h new file mode 100644 index 00000000000..ac56bdbfa61 --- /dev/null +++ b/thrift/compiler/test/fixtures/types/gen-py3/module/types.h @@ -0,0 +1,65 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * @generated + */ + +#pragma once + +#include +#include "src/gen-cpp2/module_types.h" + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::apache::thrift::fixtures::types::has_bitwise_ops>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::apache::thrift::fixtures::types::is_unscoped>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::apache::thrift::fixtures::types::MyForwardRefEnum>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::apache::thrift::fixtures::types::MyEnumA>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} + + +template<> +const std::vector>& ::thrift::py3::PyEnumTraits< + ::apache::thrift::fixtures::types::NoExceptMoveUnion::Type>::namesmap() { + static const folly::Indestructible pairs { + { + } + }; + return *pairs; +} diff --git a/thrift/compiler/test/fixtures/types/gen-py3/module/types.pxd b/thrift/compiler/test/fixtures/types/gen-py3/module/types.pxd index d805edba31d..ab69cc150de 100644 --- a/thrift/compiler/test/fixtures/types/gen-py3/module/types.pxd +++ b/thrift/compiler/test/fixtures/types/gen-py3/module/types.pxd @@ -27,6 +27,8 @@ from thrift.py3.common cimport Protocol as __Protocol from thrift.py3.types cimport bstring, move, field_ref as __FieldRef, optional_field_ref as __OptionalFieldRef from folly.optional cimport cOptional cimport include.types as _include_types +cdef extern from "src/gen-py3/module/types.h": + pass cdef extern from * nogil: cdef cppclass std_unordered_map "std::unordered_map"[T, U]: @@ -267,29 +269,17 @@ cdef extern from * nogil: cdef extern from "src/gen-cpp2/module_types.h" namespace "::apache::thrift::fixtures::types": cdef cppclass chas_bitwise_ops "::apache::thrift::fixtures::types::has_bitwise_ops": - bint operator==(chas_bitwise_ops&) - bint operator!=(chas_bitwise_ops&) - chas_bitwise_ops has_bitwise_ops__none "::apache::thrift::fixtures::types::has_bitwise_ops::none" - chas_bitwise_ops has_bitwise_ops__zero "::apache::thrift::fixtures::types::has_bitwise_ops::zero" - chas_bitwise_ops has_bitwise_ops__one "::apache::thrift::fixtures::types::has_bitwise_ops::one" - chas_bitwise_ops has_bitwise_ops__two "::apache::thrift::fixtures::types::has_bitwise_ops::two" - chas_bitwise_ops has_bitwise_ops__three "::apache::thrift::fixtures::types::has_bitwise_ops::three" + pass + cdef cppclass cis_unscoped "::apache::thrift::fixtures::types::is_unscoped": - bint operator==(cis_unscoped&) - bint operator!=(cis_unscoped&) - cis_unscoped is_unscoped__hello "::apache::thrift::fixtures::types::is_unscoped::hello" - cis_unscoped is_unscoped__world "::apache::thrift::fixtures::types::is_unscoped::world" + pass + cdef cppclass cMyForwardRefEnum "::apache::thrift::fixtures::types::MyForwardRefEnum": - bint operator==(cMyForwardRefEnum&) - bint operator!=(cMyForwardRefEnum&) - cMyForwardRefEnum MyForwardRefEnum__ZERO "::apache::thrift::fixtures::types::MyForwardRefEnum::ZERO" - cMyForwardRefEnum MyForwardRefEnum__NONZERO "::apache::thrift::fixtures::types::MyForwardRefEnum::NONZERO" + pass + cdef cppclass cMyEnumA "::apache::thrift::fixtures::types::MyEnumA": - bint operator==(cMyEnumA&) - bint operator!=(cMyEnumA&) - cMyEnumA MyEnumA__fieldA "::apache::thrift::fixtures::types::MyEnumA::fieldA" - cMyEnumA MyEnumA__fieldB "::apache::thrift::fixtures::types::MyEnumA::fieldB" - cMyEnumA MyEnumA__fieldC "::apache::thrift::fixtures::types::MyEnumA::fieldC" + pass + @@ -298,37 +288,17 @@ cdef class has_bitwise_ops(thrift.py3.types.CompiledEnum): pass -cdef chas_bitwise_ops has_bitwise_ops_to_cpp(has_bitwise_ops value) - - - - cdef class is_unscoped(thrift.py3.types.CompiledEnum): pass -cdef cis_unscoped is_unscoped_to_cpp(is_unscoped value) - - - - cdef class MyForwardRefEnum(thrift.py3.types.CompiledEnum): pass -cdef cMyForwardRefEnum MyForwardRefEnum_to_cpp(MyForwardRefEnum value) - - - - cdef class MyEnumA(thrift.py3.types.CompiledEnum): pass - -cdef cMyEnumA MyEnumA_to_cpp(MyEnumA value) - - - cdef extern from "src/gen-cpp2/module_types_custom_protocol.h" namespace "::apache::thrift::fixtures::types": cdef cppclass cdecorated_struct__isset "::apache::thrift::fixtures::types::decorated_struct::__isset": bint field diff --git a/thrift/compiler/test/fixtures/types/gen-py3/module/types.pyx b/thrift/compiler/test/fixtures/types/gen-py3/module/types.pyx index 34a575ca56f..be00619e34d 100644 --- a/thrift/compiler/test/fixtures/types/gen-py3/module/types.pyx +++ b/thrift/compiler/test/fixtures/types/gen-py3/module/types.pyx @@ -11,6 +11,7 @@ from libcpp.memory cimport shared_ptr, make_shared, unique_ptr, make_unique from libcpp.string cimport string from libcpp cimport bool as cbool from libcpp.iterator cimport inserter as cinserter +from libcpp.utility cimport move as cmove from cpython cimport bool as pbool from cython.operator cimport dereference as deref, preincrement as inc, address as ptr_address import thrift.py3.types @@ -22,6 +23,10 @@ from thrift.py3.types cimport ( constant_shared_ptr, default_inst, NOTSET as __NOTSET, + EnumData as __EnumData, + EnumFlagsData as __EnumFlagsData, + UnionTypeEnumData as __UnionTypeEnumData, + createEnumDataForUnionType as __createEnumDataForUnionType, ) cimport thrift.py3.std_libcpp as std_libcpp cimport thrift.py3.serializer as serializer @@ -32,7 +37,6 @@ from folly.optional cimport cOptional import sys import itertools from collections.abc import Sequence, Set, Mapping, Iterable -import warnings import weakref as __weakref import builtins as _builtins cimport include.types as _include_types @@ -40,529 +44,163 @@ import include.types as _include_types cimport module.types_reflection as _types_reflection -cdef object __has_bitwise_opsEnumInstances = None # Set[has_bitwise_ops] -cdef object __has_bitwise_opsEnumMembers = {} # Dict[str, has_bitwise_ops] -cdef object __has_bitwise_opsEnumUniqueValues = dict() # Dict[int, has_bitwise_ops] + +cdef __EnumData __has_bitwise_ops_enum_data = __EnumData.create(thrift.py3.types.createEnumData[chas_bitwise_ops](), has_bitwise_ops) + @__cython.internal @__cython.auto_pickle(False) -cdef class __has_bitwise_opsMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return has_bitwise_ops.none - elif cvalue == 1: - return has_bitwise_ops.zero - elif cvalue == 2: - return has_bitwise_ops.one - elif cvalue == 4: - return has_bitwise_ops.two - elif cvalue == 8: - return has_bitwise_ops.three - - raise ValueError(f'{value} is not a valid has_bitwise_ops') - - def __getitem__(cls, name): - return __has_bitwise_opsEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'none', - 'zero', - 'one', - 'two', - 'three', - ] - - def __iter__(cls): - return iter(__has_bitwise_opsEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __has_bitwise_opsEnumInstances +cdef class __has_bitwise_opsMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__has_bitwise_opsEnumInstances) + def __get_by_name(cls, str name): + return __has_bitwise_ops_enum_data.get_by_name(name) + + def __get_by_value(cls, int value): + return __has_bitwise_ops_enum_data.get_by_value(value) + def __get_all_names(cls): + return __has_bitwise_ops_enum_data.get_all_names() -cdef __has_bitwise_ops_unique_instance(int value, str name): - inst = __has_bitwise_opsEnumUniqueValues.get(value) - if inst is None: - inst = __has_bitwise_opsEnumUniqueValues[value] = has_bitwise_ops.__new__(has_bitwise_ops, value, name) - __has_bitwise_opsEnumMembers[name] = inst - return inst + def __len__(cls): + return __has_bitwise_ops_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class has_bitwise_ops(thrift.py3.types.CompiledEnum): - none = __has_bitwise_ops_unique_instance(0, "none") - zero = __has_bitwise_ops_unique_instance(1, "zero") - one = __has_bitwise_ops_unique_instance(2, "one") - two = __has_bitwise_ops_unique_instance(4, "two") - three = __has_bitwise_ops_unique_instance(8, "three") - __members__ = thrift.py3.types.MappingProxyType(__has_bitwise_opsEnumMembers) - - def __cinit__(self, value, name): - if __has_bitwise_opsEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"has_bitwise_ops.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr + cdef get_by_name(self, str name): + return __has_bitwise_ops_enum_data.get_by_name(name) - def __str__(self): - return self.__str - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, has_bitwise_ops): - warnings.warn(f"comparison not supported between instances of { has_bitwise_ops } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - def __hash__(self): - return self.__hash +__SetMetaClass( has_bitwise_ops, __has_bitwise_opsMeta) - def __reduce__(self): - return has_bitwise_ops, (self.value,) +cdef __EnumData __is_unscoped_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cis_unscoped](), is_unscoped) -__SetMetaClass( has_bitwise_ops, __has_bitwise_opsMeta) -__has_bitwise_opsEnumInstances = set(__has_bitwise_opsEnumUniqueValues.values()) - - -cdef inline chas_bitwise_ops has_bitwise_ops_to_cpp(has_bitwise_ops value): - cdef int cvalue = value.value - if cvalue == 0: - return has_bitwise_ops__none - elif cvalue == 1: - return has_bitwise_ops__zero - elif cvalue == 2: - return has_bitwise_ops__one - elif cvalue == 4: - return has_bitwise_ops__two - elif cvalue == 8: - return has_bitwise_ops__three -cdef object __is_unscopedEnumInstances = None # Set[is_unscoped] -cdef object __is_unscopedEnumMembers = {} # Dict[str, is_unscoped] -cdef object __is_unscopedEnumUniqueValues = dict() # Dict[int, is_unscoped] @__cython.internal @__cython.auto_pickle(False) -cdef class __is_unscopedMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return is_unscoped.hello - elif cvalue == 1: - return is_unscoped.world - - raise ValueError(f'{value} is not a valid is_unscoped') - - def __getitem__(cls, name): - return __is_unscopedEnumMembers[name] +cdef class __is_unscopedMeta(thrift.py3.types.EnumMeta): - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'hello', - 'world', - ] + def __get_by_name(cls, str name): + return __is_unscoped_enum_data.get_by_name(name) - def __iter__(cls): - return iter(__is_unscopedEnumUniqueValues.values()) + def __get_by_value(cls, int value): + return __is_unscoped_enum_data.get_by_value(value) - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __is_unscopedEnumInstances + def __get_all_names(cls): + return __is_unscoped_enum_data.get_all_names() def __len__(cls): - return len(__is_unscopedEnumInstances) - - -cdef __is_unscoped_unique_instance(int value, str name): - inst = __is_unscopedEnumUniqueValues.get(value) - if inst is None: - inst = __is_unscopedEnumUniqueValues[value] = is_unscoped.__new__(is_unscoped, value, name) - __is_unscopedEnumMembers[name] = inst - return inst + return __is_unscoped_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class is_unscoped(thrift.py3.types.CompiledEnum): - hello = __is_unscoped_unique_instance(0, "hello") - world = __is_unscoped_unique_instance(1, "world") - __members__ = thrift.py3.types.MappingProxyType(__is_unscopedEnumMembers) - - def __cinit__(self, value, name): - if __is_unscopedEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"is_unscoped.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value + cdef get_by_name(self, str name): + return __is_unscoped_enum_data.get_by_name(name) - def __eq__(self, other): - if not isinstance(other, is_unscoped): - warnings.warn(f"comparison not supported between instances of { is_unscoped } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return is_unscoped, (self.value,) __SetMetaClass( is_unscoped, __is_unscopedMeta) -__is_unscopedEnumInstances = set(__is_unscopedEnumUniqueValues.values()) -cdef inline cis_unscoped is_unscoped_to_cpp(is_unscoped value): - cdef int cvalue = value.value - if cvalue == 0: - return is_unscoped__hello - elif cvalue == 1: - return is_unscoped__world -cdef object __MyForwardRefEnumEnumInstances = None # Set[MyForwardRefEnum] -cdef object __MyForwardRefEnumEnumMembers = {} # Dict[str, MyForwardRefEnum] -cdef object __MyForwardRefEnumEnumUniqueValues = dict() # Dict[int, MyForwardRefEnum] +cdef __EnumData __MyForwardRefEnum_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cMyForwardRefEnum](), MyForwardRefEnum) + @__cython.internal @__cython.auto_pickle(False) -cdef class __MyForwardRefEnumMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return MyForwardRefEnum.ZERO - elif cvalue == 12: - return MyForwardRefEnum.NONZERO +cdef class __MyForwardRefEnumMeta(thrift.py3.types.EnumMeta): - raise ValueError(f'{value} is not a valid MyForwardRefEnum') + def __get_by_name(cls, str name): + return __MyForwardRefEnum_enum_data.get_by_name(name) - def __getitem__(cls, name): - return __MyForwardRefEnumEnumMembers[name] + def __get_by_value(cls, int value): + return __MyForwardRefEnum_enum_data.get_by_value(value) - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'ZERO', - 'NONZERO', - ] - - def __iter__(cls): - return iter(__MyForwardRefEnumEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyForwardRefEnumEnumInstances + def __get_all_names(cls): + return __MyForwardRefEnum_enum_data.get_all_names() def __len__(cls): - return len(__MyForwardRefEnumEnumInstances) - - -cdef __MyForwardRefEnum_unique_instance(int value, str name): - inst = __MyForwardRefEnumEnumUniqueValues.get(value) - if inst is None: - inst = __MyForwardRefEnumEnumUniqueValues[value] = MyForwardRefEnum.__new__(MyForwardRefEnum, value, name) - __MyForwardRefEnumEnumMembers[name] = inst - return inst + return __MyForwardRefEnum_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class MyForwardRefEnum(thrift.py3.types.CompiledEnum): - ZERO = __MyForwardRefEnum_unique_instance(0, "ZERO") - NONZERO = __MyForwardRefEnum_unique_instance(12, "NONZERO") - __members__ = thrift.py3.types.MappingProxyType(__MyForwardRefEnumEnumMembers) - - def __cinit__(self, value, name): - if __MyForwardRefEnumEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyForwardRefEnum.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr + cdef get_by_name(self, str name): + return __MyForwardRefEnum_enum_data.get_by_name(name) - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, MyForwardRefEnum): - warnings.warn(f"comparison not supported between instances of { MyForwardRefEnum } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return MyForwardRefEnum, (self.value,) __SetMetaClass( MyForwardRefEnum, __MyForwardRefEnumMeta) -__MyForwardRefEnumEnumInstances = set(__MyForwardRefEnumEnumUniqueValues.values()) -cdef inline cMyForwardRefEnum MyForwardRefEnum_to_cpp(MyForwardRefEnum value): - cdef int cvalue = value.value - if cvalue == 0: - return MyForwardRefEnum__ZERO - elif cvalue == 12: - return MyForwardRefEnum__NONZERO -cdef object __MyEnumAEnumInstances = None # Set[MyEnumA] -cdef object __MyEnumAEnumMembers = {} # Dict[str, MyEnumA] -cdef object __MyEnumAEnumUniqueValues = dict() # Dict[int, MyEnumA] +cdef __EnumData __MyEnumA_enum_data = __EnumData.create(thrift.py3.types.createEnumData[cMyEnumA](), MyEnumA) + @__cython.internal @__cython.auto_pickle(False) -cdef class __MyEnumAMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls): - return value - if isinstance(value, int): - cvalue = value - if cvalue == 1: - return MyEnumA.fieldA - elif cvalue == 2: - return MyEnumA.fieldB - elif cvalue == 4: - return MyEnumA.fieldC - - raise ValueError(f'{value} is not a valid MyEnumA') - - def __getitem__(cls, name): - return __MyEnumAEnumMembers[name] - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', - 'fieldA', - 'fieldB', - 'fieldC', - ] - - def __iter__(cls): - return iter(__MyEnumAEnumUniqueValues.values()) - - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __MyEnumAEnumInstances +cdef class __MyEnumAMeta(thrift.py3.types.EnumMeta): - def __len__(cls): - return len(__MyEnumAEnumInstances) + def __get_by_name(cls, str name): + return __MyEnumA_enum_data.get_by_name(name) + + def __get_by_value(cls, int value): + return __MyEnumA_enum_data.get_by_value(value) + def __get_all_names(cls): + return __MyEnumA_enum_data.get_all_names() -cdef __MyEnumA_unique_instance(int value, str name): - inst = __MyEnumAEnumUniqueValues.get(value) - if inst is None: - inst = __MyEnumAEnumUniqueValues[value] = MyEnumA.__new__(MyEnumA, value, name) - __MyEnumAEnumMembers[name] = inst - return inst + def __len__(cls): + return __MyEnumA_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class MyEnumA(thrift.py3.types.CompiledEnum): - fieldA = __MyEnumA_unique_instance(1, "fieldA") - fieldB = __MyEnumA_unique_instance(2, "fieldB") - fieldC = __MyEnumA_unique_instance(4, "fieldC") - __members__ = thrift.py3.types.MappingProxyType(__MyEnumAEnumMembers) - - def __cinit__(self, value, name): - if __MyEnumAEnumInstances is not None: - raise TypeError('__new__ is disabled in the interest of type-safety') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"MyEnumA.{name}" - self.__repr = f"<{self.__str}: {value}>" - - def __repr__(self): - return self.__repr + cdef get_by_name(self, str name): + return __MyEnumA_enum_data.get_by_name(name) - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, MyEnumA): - warnings.warn(f"comparison not supported between instances of { MyEnumA } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return MyEnumA, (self.value,) __SetMetaClass( MyEnumA, __MyEnumAMeta) -__MyEnumAEnumInstances = set(__MyEnumAEnumUniqueValues.values()) - -cdef inline cMyEnumA MyEnumA_to_cpp(MyEnumA value): - cdef int cvalue = value.value - if cvalue == 1: - return MyEnumA__fieldA - elif cvalue == 2: - return MyEnumA__fieldB - elif cvalue == 4: - return MyEnumA__fieldC -cdef object __NoExceptMoveUnion_Union_TypeEnumMembers = None +cdef __UnionTypeEnumData __NoExceptMoveUnion_union_type_enum_data = __UnionTypeEnumData.create( + __createEnumDataForUnionType[cNoExceptMoveUnion](), + __NoExceptMoveUnionType, +) @__cython.internal @__cython.auto_pickle(False) -cdef class __NoExceptMoveUnion_Union_TypeMeta(type): - def __call__(cls, value): - cdef int cvalue - if isinstance(value, cls) and value in __NoExceptMoveUnion_Union_TypeEnumMembers: - return value +cdef class __NoExceptMoveUnion_Union_TypeMeta(thrift.py3.types.EnumMeta): - if isinstance(value, int): - cvalue = value - if cvalue == 0: - return __NoExceptMoveUnionType.EMPTY - elif cvalue == 1: - return __NoExceptMoveUnionType.string_field - elif cvalue == 2: - return __NoExceptMoveUnionType.i32_field - - raise ValueError(f'{value} is not a valid NoExceptMoveUnion.Type') - - def __getitem__(cls, name): - if name == "EMPTY": - return __NoExceptMoveUnionType.EMPTY - elif name == "string_field": - return __NoExceptMoveUnionType.string_field - elif name == "i32_field": - return __NoExceptMoveUnionType.i32_field - raise KeyError(name) - - def __dir__(cls): - return ['__class__', '__doc__', '__members__', '__module__', 'EMPTY', - 'string_field', - 'i32_field', - ] - - @property - def __members__(cls): - return {m.name: m for m in cls} + def __get_by_name(cls, str name): + return __NoExceptMoveUnion_union_type_enum_data.get_by_name(name) - def __iter__(cls): - yield __NoExceptMoveUnionType.EMPTY - yield __NoExceptMoveUnionType.string_field - yield __NoExceptMoveUnionType.i32_field + def __get_by_value(cls, int value): + return __NoExceptMoveUnion_union_type_enum_data.get_by_value(value) - def __reversed__(cls): - return reversed(iter(cls)) - - def __contains__(cls, item): - if not isinstance(item, cls): - return False - return item in __NoExceptMoveUnion_Union_TypeEnumMembers + def __get_all_names(cls): + return __NoExceptMoveUnion_union_type_enum_data.get_all_names() def __len__(cls): - return 2+1 # For Empty + return __NoExceptMoveUnion_union_type_enum_data.size() @__cython.final @__cython.auto_pickle(False) cdef class __NoExceptMoveUnionType(thrift.py3.types.CompiledEnum): - EMPTY = __NoExceptMoveUnionType.__new__(__NoExceptMoveUnionType, 0, "EMPTY") - string_field = __NoExceptMoveUnionType.__new__(__NoExceptMoveUnionType, 1, "string_field") - i32_field = __NoExceptMoveUnionType.__new__(__NoExceptMoveUnionType, 2, "i32_field") - - def __cinit__(self, value, name): - if __NoExceptMoveUnion_Union_TypeEnumMembers is not None: - raise TypeError('For Safty we have disabled __new__') - self.value = value - self.name = name - self.__hash = hash(name) - self.__str = f"NoExceptMoveUnion.Type.{name}" - self.__repr = f"<{self.__str}: {value}>" + cdef get_by_name(self, str name): + return __NoExceptMoveUnion_union_type_enum_data.get_by_name(name) - def __repr__(self): - return self.__repr - - def __str__(self): - return self.__str - - def __int__(self): - return self.value - - def __eq__(self, other): - if not isinstance(other, __NoExceptMoveUnionType): - warnings.warn(f"comparison not supported between instances of { __NoExceptMoveUnionType } and {type(other)}", RuntimeWarning, stacklevel=2) - return False - return self is other - - def __hash__(self): - return self.__hash - - def __reduce__(self): - return __NoExceptMoveUnionType, (self.value,) __SetMetaClass( __NoExceptMoveUnionType, __NoExceptMoveUnion_Union_TypeMeta) -__NoExceptMoveUnion_Union_TypeEnumMembers = set(__NoExceptMoveUnionType) @__cython.auto_pickle(False) @@ -1578,10 +1216,10 @@ cdef class MyStructWithForwardRefEnum(thrift.py3.types.Struct): pass if a is not None: - deref(c_inst).a_ref().assign(MyForwardRefEnum_to_cpp(a)) + deref(c_inst).a_ref().assign(a) deref(c_inst).__isset.a = True if b is not None: - deref(c_inst).b_ref().assign(MyForwardRefEnum_to_cpp(b)) + deref(c_inst).b_ref().assign(b) deref(c_inst).__isset.b = True # in C++ you don't have to call move(), but this doesn't translate # into a C++ return statement, so you do here @@ -8087,7 +7725,7 @@ cdef class Map__MyEnumA_string(thrift.py3.types.Container): if not isinstance(item, str): raise TypeError(f"{item!r} is not of type str") - deref(c_inst)[MyEnumA_to_cpp(key)] = item.encode('UTF-8') + deref(c_inst)[key] = item.encode('UTF-8') return c_inst def __getitem__(self, key): @@ -8097,7 +7735,7 @@ cdef class Map__MyEnumA_string(thrift.py3.types.Container): if not isinstance(key, MyEnumA): raise err from None cdef cmap[cMyEnumA,string].iterator iter = deref( - self._cpp_obj).find(MyEnumA_to_cpp(key)) + self._cpp_obj).find(key) if iter == deref(self._cpp_obj).end(): raise err cdef string citem = deref(iter).second @@ -8148,7 +7786,7 @@ cdef class Map__MyEnumA_string(thrift.py3.types.Container): return False if not isinstance(key, MyEnumA): return False - cdef cMyEnumA ckey = MyEnumA_to_cpp(key) + cdef cMyEnumA ckey = key return deref(self._cpp_obj).count(ckey) > 0 def get(self, key, default=None): diff --git a/thrift/lib/py3/enums.cpp b/thrift/lib/py3/enums.cpp new file mode 100644 index 00000000000..d22496de3c2 --- /dev/null +++ b/thrift/lib/py3/enums.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) Facebook, Inc. and its 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 + +namespace thrift { +namespace py3 { + +EnumData::EnumData( + FindNameFunc fn, + FindValueFunc fv, + folly::Range names, + const std::vector& nm) + : findName_{fn}, + findValue_{fv}, + size_{names.size()}, + uncached_{names.size()}, + names_{names} { + for (auto pair : nm) { + pyToOrigNames_.emplace(pair.first, pair.second); + origToPyNames_.emplace(pair.second, pair.first); + } +} + +std::pair> EnumData::tryGetByName( + std::string_view name) const { + // return if already in cache + if (auto inst = findInCache(name)) { + return {inst, {}}; + } + // Not valid if 1. cache is complete or 2. the name has been renamed + if (uncached_.load(std::memory_order_acquire) == 0 || + origToPyNames_.find(name) != origToPyNames_.end()) { + return {nullptr, {}}; + } + // then find value with its original name + return {nullptr, findValue_(folly::get_default(pyToOrigNames_, name, name))}; +} + +std::pair EnumData::tryGetByValue( + int value) const { + auto name = findPyName(value); + if (name.empty()) { + // name not found, invalid value + return {nullptr, {}}; + } + auto inst = findInCache(name); + // if cache is complete so it has to be found + DCHECK(uncached_.load(std::memory_order_acquire) > 0 || inst); + return {inst, name}; +} + +PyObject* EnumData::tryAddToCache(int value, PyObject* obj) { + auto name = findPyName(value); + DCHECK(!name.empty()); + { + std::unique_lock wm{cacheMutex_}; + auto inserted = namesToInstances_.emplace(name, obj); + if (!inserted.second) { + return inserted.first->second; + } + } + uncached_.fetch_sub(1, std::memory_order_release); + Py_XINCREF(obj); + return obj; +} + +PyObject* EnumData::findInCache(const std::string_view name) const { + std::shared_lock lock{cacheMutex_, std::defer_lock}; + if (uncached_.load(std::memory_order_acquire) != 0) { + lock.lock(); // only hold the lock when cache not fully populated + } + return folly::get_default(namesToInstances_, name, nullptr); +} + +std::pair EnumFlagsData::tryGetByValue( + int value) const { + // check if a legit flag value + if (!isValidFlagValue(value)) { + return {nullptr, {}}; + } + // find it in the main name => instances cache + auto name = findPyName(value); + if (name.empty()) { + // name not valid, so it's a derived value + auto inst = findInFlagValuesCache(value); + // if flagValues cache pully populated, inst should be valid + DCHECK(flagValuesUncached_.load(std::memory_order_acquire) >= 0 || inst); + return {inst, ""}; + } + // otherwise it's not a derived value + auto inst = findInCache(name); + // if main cache fully populated and it's a valid value, inst should be + // valid + DCHECK(uncached_.load(std::memory_order_acquire) >= 0 || inst); + return {inst, name}; +} + +PyObject* EnumFlagsData::tryAddToFlagValuesCache( + uint32_t value, + PyObject* obj) { + { + std::unique_lock wm{flagValueCacheMutex_}; + auto inserted = flagValuesToInstances_.emplace(value, obj); + if (!inserted.second) { + return inserted.first->second; + } + } + flagValuesUncached_.fetch_sub(1, std::memory_order_release); + Py_XINCREF(obj); + return obj; +} + +std::string EnumFlagsData::getNameForDerivedValue(uint32_t value) const { + if (value == 0) { + return "0"; + } + std::vector names; + for (uint32_t mask = 1; mask <= value; mask <<= 1) { + DCHECK(mask > 0); + if ((value & mask) != 0) { + names.push_back(findName_(mask)); + } + } + return folly::join("|", names.crbegin(), names.crend()); +} + +PyObject* EnumFlagsData::findInFlagValuesCache(uint32_t value) const { + std::shared_lock lock{flagValueCacheMutex_, std::defer_lock}; + if (flagValuesUncached_.load(std::memory_order_acquire) != 0) { + lock.lock(); + } + return folly::get_default(flagValuesToInstances_, value, nullptr); +} + +} // namespace py3 +} // namespace thrift diff --git a/thrift/lib/py3/enums.h b/thrift/lib/py3/enums.h new file mode 100644 index 00000000000..beb2bb8c92b --- /dev/null +++ b/thrift/lib/py3/enums.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) Facebook, Inc. and its 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace thrift { +namespace py3 { + +template +struct PyEnumTraits { + using NamesMap = std::vector>; + static const NamesMap& namesmap(); +}; + +class EnumData { + public: + using NamePair = std::pair; + using FindNameFunc = std::string_view(int); + using FindValueFunc = std::optional(std::string_view); + EnumData( + FindNameFunc* const fn, + FindValueFunc* const fv, + folly::Range names, + const std::vector& nm); + + virtual ~EnumData() { + for (auto i : namesToInstances_) { + Py_XDECREF(i.second); + } + } + + virtual std::pair> tryGetByName( + std::string_view name) const; + + virtual std::pair tryGetByValue(int value) const; + + PyObject* tryAddToCache(int value, PyObject* obj); + + std::size_t size() const { + return size_; + } + + std::string_view getPyName(std::string_view name) const { + return folly::get_default(origToPyNames_, name, name); + } + + folly::Range getNames() const { + return names_; + } + + protected: + using NameMap = std::unordered_map; + PyObject* findInCache(std::string_view name) const; + + std::string_view findPyName(int value) const { + auto name = findName_(value); + return name.empty() ? name : getPyName(name); + } + + FindNameFunc* const findName_; + FindValueFunc* const findValue_; + const std::size_t size_; + std::atomic uncached_; + const folly::Range names_; + NameMap pyToOrigNames_; + NameMap origToPyNames_; + std::unordered_map namesToInstances_; + mutable folly::SharedMutex cacheMutex_; +}; + +class EnumFlagsData : public EnumData { + public: + EnumFlagsData( + FindNameFunc fn, + FindValueFunc fv, + folly::Range names, + const std::vector& nm, + uint32_t maxPossibleFlagValue) + : EnumData{fn, fv, names, nm}, + maxPossibleFlagValue_{maxPossibleFlagValue}, + flagValuesUncached_(1 << names.size()) {} + ~EnumFlagsData() override { + for (auto i : flagValuesToInstances_) { + Py_XDECREF(i.second); + } + } + std::pair tryGetByValue( + int value) const override; + + PyObject* tryAddToFlagValuesCache(uint32_t value, PyObject* obj); + + std::string getNameForDerivedValue(uint32_t value) const; + + uint32_t getInvertValue(uint32_t value) const { + return maxPossibleFlagValue_ ^ value; + } + + uint32_t convertNegativeValue(uint32_t value) const { + return value & maxPossibleFlagValue_; + } + + private: + bool isValidFlagValue(uint32_t value) const { + return (maxPossibleFlagValue_ | value) == maxPossibleFlagValue_; + } + + PyObject* findInFlagValuesCache(uint32_t value) const; + + const uint32_t maxPossibleFlagValue_; + mutable folly::SharedMutex flagValueCacheMutex_; + std::unordered_map flagValuesToInstances_; + std::atomic flagValuesUncached_; +}; + +namespace { +template +std::string_view enumFindNameWrapper(int value) { + const char* name = + apache::thrift::TEnumTraits::findName(static_cast(value)); + return name == nullptr ? std::string_view{} : name; +} + +template +std::optional enumFindValueWrapper(const std::string_view name) { + T v{}; + const auto c = apache::thrift::TEnumTraits::findValue(name.data(), &v); + return c ? std::optional{static_cast(v)} : std::nullopt; +} +} // namespace + +template +EnumData* createEnumData() { + using Traits = apache::thrift::TEnumTraits; + return new EnumData( + enumFindNameWrapper, + enumFindValueWrapper, + Traits::names, + PyEnumTraits::namesmap()); +} + +template +EnumFlagsData* createEnumFlagsData() { + using Traits = apache::thrift::TEnumTraits; + uint32_t s = 0; + for (auto value : apache::thrift::TEnumTraits::values) { + s |= static_cast(value); + } + return new EnumFlagsData( + enumFindNameWrapper, + enumFindValueWrapper, + Traits::names, + PyEnumTraits::namesmap(), + s); +} + +template +EnumData* createEnumDataForUnionType() { + using type = typename T::Type; + using Traits = apache::thrift::TEnumTraits; + return new EnumData( + enumFindNameWrapper, + enumFindValueWrapper, + Traits::names, + PyEnumTraits::namesmap()); +} + +} // namespace py3 +} // namespace thrift diff --git a/thrift/lib/py3/std_libcpp.pxd b/thrift/lib/py3/std_libcpp.pxd index 397ffe6db05..3d47881592e 100644 --- a/thrift/lib/py3/std_libcpp.pxd +++ b/thrift/lib/py3/std_libcpp.pxd @@ -77,3 +77,23 @@ cdef extern from "" namespace "std" nogil: Iter2 first2, Iter2 last2, OutputIter result) + +cdef extern from "" namespace "std" nogil: + cdef cppclass optional "std::optional"[T]: + optional() + optional(T&& val) + bint has_value() + T& value() + T value_or(T&& altValue) + void reset() + +cdef extern from "" namespace "std" nogil: + cdef cppclass string_view "std::string_view": + string_view() + string_view(const char*) + size_t size() + bint empty() + const char* data() + +cdef inline str sv_to_str(string_view sv) except +: + return sv.data().decode("utf-8") diff --git a/thrift/lib/py3/test/unions.py b/thrift/lib/py3/test/unions.py index 6b22e051719..cc09eecf3eb 100644 --- a/thrift/lib/py3/test/unions.py +++ b/thrift/lib/py3/test/unions.py @@ -55,7 +55,7 @@ def test_union_usage(self) -> None: self.assertEqual(x.type, Integers.Type.large) self.assertEqual(x.value, value) # Hashing Works - s = set([x]) + s = {x} self.assertIn(x, s) # Repr is useful rx = repr(x) diff --git a/thrift/lib/py3/types.pxd b/thrift/lib/py3/types.pxd index 3d211955ed6..fde21ddc5ea 100644 --- a/thrift/lib/py3/types.pxd +++ b/thrift/lib/py3/types.pxd @@ -14,22 +14,26 @@ # distutils: language=c++ from cpython.bytes cimport PyBytes_AsStringAndSize -from cpython.object cimport PyTypeObject, Py_LT, Py_EQ +from cpython.object cimport PyObject, PyTypeObject, Py_LT, Py_EQ from folly.iobuf cimport cIOBuf, IOBuf +from folly.range cimport StringPiece as cStringPiece, Range as cRange from libc.stdint cimport uint32_t from libcpp.string cimport string -from libcpp.memory cimport shared_ptr +from libcpp.memory cimport shared_ptr, unique_ptr +from libcpp.vector cimport vector +from libcpp.pair cimport pair from collections.abc import Iterable +from thrift.py3.std_libcpp cimport string_view, optional, sv_to_str from thrift.py3.common cimport Protocol -cdef extern from "": +cdef extern from *: """ - static CYTHON_INLINE void SetMetaClass(PyTypeObject* t, PyTypeObject* m) - { - Py_TYPE(t) = m; - PyType_Modified(t); - } + static CYTHON_INLINE void SetMetaClass(PyTypeObject* t, PyTypeObject* m) + { + Py_TYPE(t) = m; + PyType_Modified(t); + } """ void SetMetaClass(PyTypeObject* t, PyTypeObject* m) @@ -37,6 +41,51 @@ cdef extern from "thrift/lib/py3/types.h" namespace "::thrift::py3" nogil: shared_ptr[T] constant_shared_ptr[T](T) const T& default_inst[T]() +ctypedef PyObject* PyObjectPtr +ctypedef optional[int] cOptionalInt + +cdef extern from "thrift/lib/py3/enums.h" namespace "::thrift::py3" nogil: + cdef cppclass cEnumData "::thrift::py3::EnumData": + pair[PyObjectPtr, cOptionalInt] tryGetByName(string_view name) except + + pair[PyObjectPtr, string_view] tryGetByValue(int value) except + + PyObject* tryAddToCache(int value, PyObject* obj) except + + size_t size() + string_view getPyName(string_view name) + cRange[const cStringPiece*] getNames() + cdef cppclass cEnumFlagsData "::thrift::py3::EnumFlagsData"(cEnumData): + PyObject* tryAddToFlagValuesCache(int value, PyObject* obj) except + + string getNameForDerivedValue(int value) except + + int getInvertValue(int value) except + + int convertNegativeValue(int value) except + + cEnumData* createEnumData[T]() except + + cEnumFlagsData* createEnumFlagsData[T]() except + + cEnumData* createEnumDataForUnionType[T]() except + + + +cdef class EnumData: + cdef unique_ptr[cEnumData] _cpp_obj + cdef type _py_type + cdef get_by_name(self, str name) + cdef get_by_value(self, int value) + cdef PyObject* _add_to_cache(self, str name, int value) except * + cdef int size(self) + cdef void _value_error(self, int value) except * + @staticmethod + cdef EnumData create(cEnumData* ptr, py_type) + +cdef class EnumFlagsData(EnumData): + cdef get_invert(self, uint32_t value) + @staticmethod + cdef EnumFlagsData create(cEnumFlagsData* ptr, py_type) + +cdef class UnionTypeEnumData(EnumData): + cdef object __empty + @staticmethod + cdef UnionTypeEnumData create(cEnumData* ptr, py_type) + +cdef class EnumMeta(type): + pass + cdef class __NotSet: pass @@ -66,6 +115,7 @@ cdef class CompiledEnum: cdef object __hash cdef object __str cdef object __repr + cdef get_by_name(self, str name) cdef class Flag(CompiledEnum): @@ -125,18 +175,6 @@ cdef inline string bytes_to_string(bytes b) except*: return move(string(data, length)) # there is a temp because string can raise -cdef inline uint32_t largest_flag(uint32_t v): - """ - Given a 32bit flag field, this identifies the largest bit flag that v is - composed of - """ - v |= (v >> 1) - v |= (v >> 2) - v |= (v >> 4) - v |= (v >> 8) - v |= (v >> 16) - return v ^ (v >> 1) - cdef extern from "thrift/lib/cpp2/FieldRef.h" namespace "apache::thrift" nogil: cdef cppclass field_ref[T]: diff --git a/thrift/lib/py3/types.pyi b/thrift/lib/py3/types.pyi index 920cc7f753a..a7ab32d392a 100644 --- a/thrift/lib/py3/types.pyi +++ b/thrift/lib/py3/types.pyi @@ -55,9 +55,10 @@ class Container: ... class EnumMeta(type): def __iter__(self: Type[_T]) -> Iterator[_T]: ... - def __revered__(self: Type[_T]) -> Iterator[_T]: ... - def __contains__(self: Type[_T], member: Any) -> bool: ... + def __reversed__(self: Type[_T]) -> Iterator[_T]: ... + def __contains__(self: Type[_T], item: Any) -> bool: ... def __getitem__(self: Type[_T], name: str) -> _T: ... + def __getattr__(self: Type[_T], name: str) -> _T: ... def __len__(self) -> int: ... @property def __members__(self: Type[_T]) -> Mapping[str, _T]: ... @@ -65,12 +66,14 @@ class EnumMeta(type): class Enum(metaclass=EnumMeta): name: str value: int + def __getattr__(self, name: str) -> eT: ... def __init__(self: eT, value: tUnion[eT, int]) -> None: ... # __call__ for meta def __repr__(self) -> str: ... def __str__(self) -> str: ... def __hash__(self) -> int: ... def __reduce__(self: eT) -> Tuple[Type[eT], Tuple[int]]: ... def __int__(self) -> int: ... + def __eq__(self, other: Any) -> bool: ... class Flag(Enum): def __contains__(self: eT, other: eT) -> bool: ... diff --git a/thrift/lib/py3/types.pyx b/thrift/lib/py3/types.pyx index 939c931b2b0..3e5b2301586 100644 --- a/thrift/lib/py3/types.pyx +++ b/thrift/lib/py3/types.pyx @@ -13,7 +13,11 @@ # limitations under the License. import enum +import warnings cimport cython + +from cython.operator cimport dereference as deref, postincrement as inc +from folly.cast cimport down_cast_ptr from folly.iobuf import IOBuf from types import MappingProxyType @@ -82,12 +86,220 @@ cdef class Container: pass +@cython.auto_pickle(False) +cdef class EnumData: + @staticmethod + cdef EnumData create(cEnumData* ptr, py_type): + cdef EnumData inst = EnumData.__new__(EnumData) + inst._py_type = py_type + inst._cpp_obj = unique_ptr[cEnumData](ptr) + return inst + + cdef get_by_name(self, str name): + cdef bytes name_bytes = name.encode("utf-8") # to keep the buffer alive + cdef string_view name_sv = string_view(name_bytes) + cdef pair[PyObjectPtr, cOptionalInt] r = self._cpp_obj.get().tryGetByName(name_sv) + cdef PyObject* inst = r.first + cdef optional[int] value = r.second + if inst != NULL: + return inst + if not value.has_value(): + raise AttributeError(f"'{self._py_type.__name__}' has no attribute '{name}'") + return self._add_to_cache(name, value.value()) + + cdef get_by_value(self, int value): + if value < -(1<<31) or value >= (1 << 31): + self._value_error(value) + cdef pair[PyObjectPtr, string_view] r = self._cpp_obj.get().tryGetByValue(value) + cdef PyObject* inst = r.first + cdef string_view name = r.second + if inst != NULL: + return inst + if name.data() == NULL: + self._value_error(value) + return self._add_to_cache(sv_to_str(name), value) + + cdef PyObject* _add_to_cache(self, str name, int value) except *: + new_inst = self._py_type.__new__(self._py_type, name, value, NOTSET) + return self._cpp_obj.get().tryAddToCache( + value, + new_inst + ) + + def get_all_names(self): + cdef cEnumData* cpp_obj_ptr = self._cpp_obj.get() + cdef cRange[const cStringPiece*] names = cpp_obj_ptr.getNames() + cdef cStringPiece name + for name in names: + yield sv_to_str(cpp_obj_ptr.getPyName(string_view(name.data()))) + + cdef int size(self): + return self._cpp_obj.get().size() + + cdef void _value_error(self, int value) except *: + raise ValueError(f"{value} is not a valid {self._py_type.__name__}") + + +@cython.auto_pickle(False) +cdef class EnumFlagsData(EnumData): + + @staticmethod + cdef EnumFlagsData create(cEnumFlagsData* ptr, py_type): + cdef EnumFlagsData inst = EnumFlagsData.__new__(EnumFlagsData) + inst._py_type = py_type + inst._cpp_obj = unique_ptr[cEnumData](ptr) + return inst + + cdef get_by_value(self, int value): + cdef cEnumFlagsData* cpp_obj_ptr = down_cast_ptr[ + cEnumFlagsData, cEnumData](self._cpp_obj.get()) + if value < 0: + value = cpp_obj_ptr.convertNegativeValue(value) + cdef pair[PyObjectPtr, string_view] r = cpp_obj_ptr.tryGetByValue(value) + cdef PyObject* inst = r.first + cdef string_view name = r.second + if inst != NULL: + return inst + if name.data() == NULL: + self._value_error(value) + if not name.empty(): + # it's not a derived value + return self._add_to_cache(sv_to_str(name), value) + # it's a derived value + new_inst = self._py_type.__new__( + self._py_type, + cpp_obj_ptr.getNameForDerivedValue(value).decode("utf-8"), + value, + NOTSET, + ) + return cpp_obj_ptr.tryAddToFlagValuesCache(value, new_inst) + + cdef get_invert(self, uint32_t value): + cdef cEnumFlagsData* cpp_obj_ptr = down_cast_ptr[ + cEnumFlagsData, cEnumData](self._cpp_obj.get()) + return self.get_by_value(cpp_obj_ptr.getInvertValue(value)) + +@cython.auto_pickle(False) +cdef class UnionTypeEnumData(EnumData): + + @staticmethod + cdef UnionTypeEnumData create(cEnumData* ptr, py_type): + cdef UnionTypeEnumData inst = UnionTypeEnumData.__new__(UnionTypeEnumData) + inst._py_type = py_type + inst._cpp_obj = unique_ptr[cEnumData](ptr) + inst.__empty = py_type.__new__(py_type, "EMPTY", 0, NOTSET) + return inst + + def get_all_names(self): + yield "EMPTY" + yield from EnumData.get_all_names(self) + + cdef get_by_name(self, str name): + if name == "EMPTY": + return self.__empty + return EnumData.get_by_name(self, name) + + cdef get_by_value(self, int value): + if value == 0: + return self.__empty + return EnumData.get_by_value(self, value) + + cdef int size(self): + return EnumData.size(self) + 1 # for EMPTY + + +@cython.auto_pickle(False) +cdef class EnumMeta(type): + def __get_by_name(cls, str name): + return NotImplemented + + def __get_by_value(cls, int value): + return NotImplemented + + def __get_all_names(cls): + return NotImplemented + + def __call__(cls, value): + if isinstance(value, cls): + return value + if not isinstance(value, int): + raise ValueError(f"{repr(value)} is not a valid {cls.__name__}") + return cls.__get_by_value(value) + + def __getitem__(cls, name): + if not isinstance(name, str): + raise KeyError(name) + try: + return cls.__get_by_name(str(name)) + except AttributeError: + raise KeyError(name) + + def __getattr__(cls, name): + return cls.__get_by_name(name) + + def __iter__(cls): + for name in cls.__get_all_names(): + yield cls.__get_by_name(name) + + def __reversed__(cls): + return reversed(iter(cls)) + + def __contains__(cls, item): + if not isinstance(item, cls): + return False + return item in cls.__iter__() + + def __len__(cls): + return NotImplemented + + @property + def __members__(cls): + return MappingProxyType({inst.name: inst for inst in cls.__iter__()}) + + def __dir__(cls): + return ['__class__', '__doc__', '__members__', '__module__'] + [name for name in cls.__get_all_names()] + + @cython.auto_pickle(False) cdef class CompiledEnum: """ Base class for all thrift Enum """ - pass + def __cinit__(self, name, value, __NotSet guard = None): + if guard is not NOTSET: + raise TypeError('__new__ is disabled in the interest of type-safety') + self.name = name + self.value = value + self.__hash = hash(name) + self.__str = f"{type(self).__name__}.{name}" + self.__repr = f"<{self.__str}: {value}>" + + cdef get_by_name(self, str name): + return NotImplemented + + def __getattr__(self, name): + return self.get_by_name(name) + + def __repr__(self): + return self.__repr + + def __str__(self): + return self.__str + + def __int__(self): + return self.value + + def __hash__(self): + return self.__hash + + def __reduce__(self): + return type(self), (self.value,) + + def __eq__(self, other): + if type(other) is not type(self): + warnings.warn(f"comparison not supported between instances of { type(self) } and {type(other)}", RuntimeWarning, stacklevel=2) + return False + return self is other Enum = CompiledEnum # I wanted to call the base class Enum, but there is a cython bug @@ -100,7 +312,34 @@ cdef class Flag(CompiledEnum): """ Base class for all thrift Flag """ - pass + def __contains__(self, other): + if type(other) is not type(self): + return NotImplemented + return other.value & self.value == other.value + + def __bool__(self): + return bool(self.value) + + def __or__(self, other): + cls = type(self) + if type(other) is not cls: + return NotImplemented + return cls(self.value | other.value) + + def __and__(self, other): + cls = type(self) + if type(other) is not cls: + return NotImplemented + return cls(self.value & other.value) + + def __xor__(self, other): + cls = type(self) + if type(other) is not cls: + return NotImplemented + return cls(self.value ^ other.value) + + def __invert__(self): + return NotImplemented cdef class BadEnum: