Skip to content

Commit

Permalink
Expose getStandardImmutableDefaultValueForType to python
Browse files Browse the repository at this point in the history
Summary: The motivation is that in Thrift Patch, we want to be able to ensure a field to the default value. We need a way to get the standard default value in python.

Reviewed By: praihan

Differential Revision: D66269102

fbshipit-source-id: 0a033a5d2e931bb88f6fc25f978758a67daf5404
  • Loading branch information
TJ Yin authored and facebook-github-bot committed Nov 25, 2024
1 parent 1955b62 commit 688937e
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 0 deletions.
50 changes: 50 additions & 0 deletions third-party/thrift/src/thrift/lib/python/test/typeinfo_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from thrift.python.types import (
AdaptedTypeInfo,
EnumTypeInfo,
get_standard_immutable_default_value_for_type,
IntegerTypeInfo,
IOBufTypeInfo,
ListTypeInfo,
Expand All @@ -38,6 +39,15 @@
StringTypeInfo,
StructTypeInfo,
TypeInfo,
typeinfo_binary,
typeinfo_bool,
typeinfo_byte,
typeinfo_double,
typeinfo_float,
typeinfo_i16,
typeinfo_i32,
typeinfo_i64,
typeinfo_string,
)

# This python file serves as a boilerplate code for executing tests written
Expand Down Expand Up @@ -125,3 +135,43 @@ def test_MutableMapTypeInfo(self) -> None:

def test_MutableStructTypeInfo(self) -> None:
CTests(self).test_MutableStructTypeInfo()

def test_StandardDefaultValue(self) -> None:
self.assertEqual(
get_standard_immutable_default_value_for_type(typeinfo_bool), False
)
self.assertEqual(
get_standard_immutable_default_value_for_type(typeinfo_byte), 0
)
self.assertEqual(get_standard_immutable_default_value_for_type(typeinfo_i16), 0)
self.assertEqual(get_standard_immutable_default_value_for_type(typeinfo_i32), 0)
self.assertEqual(get_standard_immutable_default_value_for_type(typeinfo_i64), 0)
self.assertEqual(
get_standard_immutable_default_value_for_type(typeinfo_float), 0.0
)
self.assertEqual(
get_standard_immutable_default_value_for_type(typeinfo_double), 0.0
)
self.assertEqual(
get_standard_immutable_default_value_for_type(typeinfo_string), ""
)
self.assertEqual(
get_standard_immutable_default_value_for_type(typeinfo_binary), b""
)

self.assertEqual(
get_standard_immutable_default_value_for_type(
ListTypeInfo(typeinfo_string)
),
[],
)
self.assertEqual(
get_standard_immutable_default_value_for_type(SetTypeInfo(typeinfo_string)),
set(),
)
self.assertEqual(
get_standard_immutable_default_value_for_type(
MapTypeInfo(typeinfo_string, typeinfo_string)
),
{},
)
10 changes: 10 additions & 0 deletions third-party/thrift/src/thrift/lib/python/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1692,6 +1692,16 @@ const detail::TypeInfo iobufTypeInfo{
/* .typeExt */ &ioBufFieldType,
};

PyObject* getStandardImmutableDefaultValuePtrForType(
const detail::TypeInfo& typeInfo) {
auto ret = getStandardImmutableDefaultValueForType(typeInfo);
return std::get<0>(ret).release();
}
PyObject* getStandardMutableDefaultValuePtrForType(
const detail::TypeInfo& typeInfo) {
auto ret = getStandardMutableDefaultValueForType(typeInfo);
return std::get<0>(ret).release();
}
} // namespace apache::thrift::python

namespace apache::thrift::python::capi {
Expand Down
39 changes: 39 additions & 0 deletions third-party/thrift/src/thrift/lib/python/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,45 @@ inline const PyObject* getListObjectItemBase(const void* pyList) {
return reinterpret_cast<PyObject*>(&PyList_GET_ITEM(pyList, 0));
}

/**
* Returns the appropriate standard immutable default value for the given
* `typeInfo`.
*
* The standard default values are as follows:
* * `0L` for integral numbers.
* * `0d` for floating-point numbers.
* * `false` for booleans.
* * `""` (i.e., the empty string) for strings and `binary` fields (or an
* empty `IOBuf` if applicable).
* * An empty `tuple` for lists and maps.
* * An empty `frozenset` for sets.
* * A recursively default-initialized instance for structs and unions.
*
* @throws if there is no standard default value
*/
PyObject* getStandardImmutableDefaultValuePtrForType(
const detail::TypeInfo& typeInfo);

/**
* Returns the appropriate standard mutable default value for the given
* `typeInfo`.
*
* The standard default values are as follows:
* * `0L` for integral numbers.
* * `0d` for floating-point numbers.
* * `false` for booleans.
* * `""` (i.e., the empty string) for strings and `binary` fields (or an
* empty `IOBuf` if applicable).
* * An empty `list` for lists.
* * An empty `dict` for maps.
* * An empty `set` for sets.
* * A recursively default-initialized instance for structs and unions.
*
* @throws if there is no standard default value
*/
PyObject* getStandardMutableDefaultValuePtrForType(
const detail::TypeInfo& typeInfo);

} // namespace apache::thrift::python

namespace apache::thrift::python::capi {
Expand Down
3 changes: 3 additions & 0 deletions third-party/thrift/src/thrift/lib/python/types.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ cdef extern from "<thrift/lib/python/types.h>" namespace "::apache::thrift::pyth
const cDynamicStructInfo& structInfo
) except+
cdef void setStructIsset(object, int index, bint set) except+
cdef object getStandardImmutableDefaultValuePtrForType(
const cTypeInfo& typeInfo
) except+

cdef const cTypeInfo& boolTypeInfo
cdef const cTypeInfo& byteTypeInfo
Expand Down
23 changes: 23 additions & 0 deletions third-party/thrift/src/thrift/lib/python/types.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

import enum
import typing
from typing import Never

from folly.iobuf import IOBuf

from thrift.python.adapter import Adapter
from thrift.python.exceptions import GeneratedError
Expand Down Expand Up @@ -197,6 +200,26 @@ def update_nested_field(
obj: sT, path_to_values: typing.Mapping[str, typing.Any]
) -> sT: ...

_DefaultFieldValue = typing.Union[
bool,
int,
float,
str,
bytes,
IOBuf,
Enum,
Struct,
Union,
GeneratedError,
typing.Sequence[Never],
typing.AbstractSet[Never],
typing.Mapping[Never, Never],
]

def get_standard_immutable_default_value_for_type(
type_info: AnyTypeInfo,
) -> _DefaultFieldValue: ...

class _fbthrift_ResponseStreamResult(Struct, typing.Generic[TChunk]):
success: typing.Final[TChunk]

Expand Down
4 changes: 4 additions & 0 deletions third-party/thrift/src/thrift/lib/python/types.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2539,3 +2539,7 @@ cdef class ServiceInterface:

async def onStopRequested(self):
pass


def get_standard_immutable_default_value_for_type(TypeInfoBase typeinfo):
return typeinfo.to_python_value(getStandardImmutableDefaultValuePtrForType(typeinfo.get_cTypeInfo()[0]))

0 comments on commit 688937e

Please sign in to comment.