Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5e96353

Browse files
PYTHON-5508 - Add built-in DecimalEncoder and DecimalDecoder (#2499)
1 parent 9a9a65c commit 5e96353

File tree

4 files changed

+50
-46
lines changed

4 files changed

+50
-46
lines changed

‎bson/decimal128.py‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020

2121
import decimal
2222
import struct
23+
from decimal import Decimal
2324
from typing import Any, Sequence, Tuple, Type, Union
2425

26+
from bson.codec_options import TypeDecoder, TypeEncoder
27+
2528
_PACK_64 = struct.Struct("<Q").pack
2629
_UNPACK_64 = struct.Struct("<Q").unpack
2730

@@ -58,6 +61,42 @@
5861
_VALUE_OPTIONS = Union[decimal.Decimal, float, str, Tuple[int, Sequence[int], int]]
5962

6063

64+
class DecimalEncoder(TypeEncoder):
65+
"""Converts Python :class:`decimal.Decimal` to BSON :class:`Decimal128`.
66+
67+
For example::
68+
opts = CodecOptions(type_registry=TypeRegistry([DecimalEncoder()]))
69+
bson.encode({"d": decimal.Decimal('1.0')}, codec_options=opts)
70+
71+
.. versionadded:: 4.15
72+
"""
73+
74+
@property
75+
def python_type(self) -> Type[Decimal]:
76+
return Decimal
77+
78+
def transform_python(self, value: Any) -> Decimal128:
79+
return Decimal128(value)
80+
81+
82+
class DecimalDecoder(TypeDecoder):
83+
"""Converts BSON :class:`Decimal128` to Python :class:`decimal.Decimal`.
84+
85+
For example::
86+
opts = CodecOptions(type_registry=TypeRegistry([DecimalDecoder()]))
87+
bson.decode(data, codec_options=opts)
88+
89+
.. versionadded:: 4.15
90+
"""
91+
92+
@property
93+
def bson_type(self) -> Type[Decimal128]:
94+
return Decimal128
95+
96+
def transform_bson(self, value: Any) -> decimal.Decimal:
97+
return value.to_decimal()
98+
99+
61100
def create_decimal128_context() -> decimal.Context:
62101
"""Returns an instance of :class:`decimal.Context` appropriate
63102
for working with IEEE-754 128-bit decimal floating point values.

‎doc/changelog.rst‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
Changelog
22
=========
3+
Changes in Version 4.15.0 (XXXX/XX/XX)
4+
--------------------------------------
5+
PyMongo 4.15 brings a number of changes including:
6+
7+
- Added :class:`bson.decimal128.DecimalEncoder` and :class:`bson.decimal128.DecimalDecoder`
8+
to support encoding and decoding of BSON Decimal128 values to decimal.Decimal values using the TypeRegistry API.
9+
310
Changes in Version 4.14.1 (2025年08月19日)
411
--------------------------------------
512

‎test/asynchronous/test_custom_types.py‎

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from random import random
2424
from typing import Any, Tuple, Type, no_type_check
2525

26+
from bson.decimal128 import DecimalDecoder, DecimalEncoder
2627
from gridfs.asynchronous.grid_file import AsyncGridIn, AsyncGridOut
2728

2829
sys.path[0:0] = [""]
@@ -59,29 +60,7 @@
5960
_IS_SYNC = False
6061

6162

62-
class DecimalEncoder(TypeEncoder):
63-
@property
64-
def python_type(self):
65-
return Decimal
66-
67-
def transform_python(self, value):
68-
return Decimal128(value)
69-
70-
71-
class DecimalDecoder(TypeDecoder):
72-
@property
73-
def bson_type(self):
74-
return Decimal128
75-
76-
def transform_bson(self, value):
77-
return value.to_decimal()
78-
79-
80-
class DecimalCodec(DecimalDecoder, DecimalEncoder):
81-
pass
82-
83-
84-
DECIMAL_CODECOPTS = CodecOptions(type_registry=TypeRegistry([DecimalCodec()]))
63+
DECIMAL_CODECOPTS = CodecOptions(type_registry=TypeRegistry([DecimalEncoder(), DecimalDecoder()]))
8564

8665

8766
class UndecipherableInt64Type:

‎test/test_custom_types.py‎

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from random import random
2424
from typing import Any, Tuple, Type, no_type_check
2525

26+
from bson.decimal128 import DecimalDecoder, DecimalEncoder
2627
from gridfs.synchronous.grid_file import GridIn, GridOut
2728

2829
sys.path[0:0] = [""]
@@ -59,29 +60,7 @@
5960
_IS_SYNC = True
6061

6162

62-
class DecimalEncoder(TypeEncoder):
63-
@property
64-
def python_type(self):
65-
return Decimal
66-
67-
def transform_python(self, value):
68-
return Decimal128(value)
69-
70-
71-
class DecimalDecoder(TypeDecoder):
72-
@property
73-
def bson_type(self):
74-
return Decimal128
75-
76-
def transform_bson(self, value):
77-
return value.to_decimal()
78-
79-
80-
class DecimalCodec(DecimalDecoder, DecimalEncoder):
81-
pass
82-
83-
84-
DECIMAL_CODECOPTS = CodecOptions(type_registry=TypeRegistry([DecimalCodec()]))
63+
DECIMAL_CODECOPTS = CodecOptions(type_registry=TypeRegistry([DecimalEncoder(), DecimalDecoder()]))
8564

8665

8766
class UndecipherableInt64Type:

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /