Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-thriftpy2 for openSUSE:Factory checked in at 2024-03-13 22:18:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-thriftpy2 (Old) and /work/SRC/openSUSE:Factory/.python-thriftpy2.new.1770 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-thriftpy2" Wed Mar 13 22:18:02 2024 rev:9 rq:1157069 version:0.4.20 Changes: -------- --- /work/SRC/openSUSE:Factory/python-thriftpy2/python-thriftpy2.changes 2023-08-14 22:35:27.084298510 +0200 +++ /work/SRC/openSUSE:Factory/.python-thriftpy2.new.1770/python-thriftpy2.changes 2024-03-13 22:18:56.985092187 +0100 @@ -1,0 +2,15 @@ +Tue Mar 12 01:03:03 UTC 2024 - Steve Kowalik <steven.kowa...@suse.com> + +- Update to 0.4.20: + * Fix another compatibility issue with legacy Python. + * Fix a compatibility issue with legacy Python. + * Make the import hook compatible with Python3.12. + * Added a ``strict_decode`` option to all protocols to force all + strings in the response to be decoded to ``str``. + * Allow annotations in the ``Union`` type. + * Fixed the ``message_type`` in oneway request. + * Fix Cython build error in latest Python3 version +- Drop restriction on Cython. +- Switch to pyproject macros. + +------------------------------------------------------------------- Old: ---- v0.4.16.tar.gz New: ---- v0.4.20.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-thriftpy2.spec ++++++ --- /var/tmp/diff_new_pack.ZFjEUC/_old 2024-03-13 22:18:58.161135541 +0100 +++ /var/tmp/diff_new_pack.ZFjEUC/_new 2024-03-13 22:18:58.165135688 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-thriftpy2 # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,23 +17,24 @@ Name: python-thriftpy2 -Version: 0.4.16 +Version: 0.4.20 Release: 0 Summary: Pure python implementation of Apache Thrift License: MIT -Group: Development/Languages/Python URL: https://github.com/Thriftpy/thriftpy2 Source0: https://github.com/Thriftpy/thriftpy2/archive/v%{version}.tar.gz Source1: new_certs.tar.xz -BuildRequires: %{python_module Cython >= 0.28.4 with %python-Cython < 3} +BuildRequires: %{python_module Cython} BuildRequires: %{python_module dbm} BuildRequires: %{python_module devel} +BuildRequires: %{python_module pip} BuildRequires: %{python_module ply >= 3.4} BuildRequires: %{python_module pytest >= 2.8} BuildRequires: %{python_module pytest-asyncio} BuildRequires: %{python_module setuptools} BuildRequires: %{python_module six} BuildRequires: %{python_module tornado >= 5.0} +BuildRequires: %{python_module wheel} BuildRequires: fdupes BuildRequires: python-rpm-macros BuildRequires: python3-pytest-asyncio @@ -54,10 +55,10 @@ %build export CFLAGS="%{optflags}" -%python_build +%pyproject_wheel %install -%python_install +%pyproject_install %python_expand %fdupes %{buildroot}%{$python_sitearch} %{python_expand # remove devel files find %{buildroot}%{$python_sitearch} -name '*.h' -exec rm {} \; @@ -74,5 +75,5 @@ %license LICENSE %doc CHANGES.rst README.rst %{python_sitearch}/thriftpy2 -%{python_sitearch}/thriftpy2-%{version}*-info +%{python_sitearch}/thriftpy2-%{version}.dist-info ++++++ v0.4.16.tar.gz -> v0.4.20.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/.github/workflows/python-package.yml new/thriftpy2-0.4.20/.github/workflows/python-package.yml --- old/thriftpy2-0.4.16/.github/workflows/python-package.yml 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/.github/workflows/python-package.yml 2024-02-28 11:00:33.000000000 +0100 @@ -12,11 +12,11 @@ jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v3 @@ -27,7 +27,7 @@ - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install flake8 pytest pytest-asyncio + python -m pip install flake8 pytest pytest-asyncio cython if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with flake8 run: | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/.gitignore new/thriftpy2-0.4.20/.gitignore --- old/thriftpy2-0.4.16/.gitignore 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/.gitignore 2024-02-28 11:00:33.000000000 +0100 @@ -49,3 +49,5 @@ pyvenv.cfg share/* + +venv diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/CHANGES.rst new/thriftpy2-0.4.20/CHANGES.rst --- old/thriftpy2-0.4.16/CHANGES.rst 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/CHANGES.rst 2024-02-28 11:00:33.000000000 +0100 @@ -3,15 +3,41 @@ 0.4.x ~~~~~ + +Version 0.4.20 +-------------- + +- Fix another compatibility issue with legacy Python. + +Version 0.4.19 +-------------- + +- Fix a compatibility issue with legacy Python. + +Version 0.4.18 +-------------- + +- Make the import hook compatible with Python3.12. +- Added a ``strict_decode`` option to all protocols to force all strings in the response to be decoded to ``str``. +- Allow annotations in the ``Union`` type. +- Fixed the ``message_type`` in oneway request. + +Version 0.4.17 +-------------- + +Released on Sep 27, 2023. + +- Fix Cython build error in latest Python3 version + Version 0.4.16 -------------- +-------------- Released on Nov 15, 2022. - Fix unexpected binary type id in TBinaryTransport serialization Version 0.4.15 -------------- +-------------- Released on Nov 8, 2021. @@ -20,7 +46,7 @@ - Fix some socket leaking cases in aio support Version 0.4.14 -------------- +-------------- Released on Jan 21, 2021. @@ -29,7 +55,7 @@ .. _2-#157: https://github.com/Thriftpy/thriftpy2/pull/157 Version 0.4.13 -------------- +-------------- Released on Jan 19, 2021. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/pyproject.toml new/thriftpy2-0.4.20/pyproject.toml --- old/thriftpy2-0.4.16/pyproject.toml 1970-01-01 01:00:00.000000000 +0100 +++ new/thriftpy2-0.4.20/pyproject.toml 2024-02-28 11:00:33.000000000 +0100 @@ -0,0 +1,2 @@ +[build-system] +requires = ["setuptools", "cython>=0.28.4,<4"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/setup.py new/thriftpy2-0.4.20/setup.py --- old/thriftpy2-0.4.16/setup.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/setup.py 2024-02-28 11:00:33.000000000 +0100 @@ -19,7 +19,8 @@ ] tornado_requires = [ - "tornado>=4.0,<6.0", + "tornado>=4.0,<7.0; python_version>='3.12'", + "tornado>=4.0,<6.0; python_version<'3.12'", ] try: @@ -31,7 +32,6 @@ pass dev_requires = [ - "cython>=0.28.4", "flake8>=2.5", "pytest>=2.8", "sphinx-rtd-theme>=0.1.9", @@ -40,13 +40,6 @@ ] + tornado_requires -# cython detection -try: - from Cython.Build import cythonize - CYTHON = True -except ImportError: - CYTHON = False - cmdclass = {} ext_modules = [] @@ -56,11 +49,10 @@ # only build ext in CPython with UNIX platform if UNIX and not PYPY: - # rebuild .c files if cython available - if CYTHON: - cythonize("thriftpy2/transport/cybase.pyx") - cythonize("thriftpy2/transport/**/*.pyx") - cythonize("thriftpy2/protocol/cybin/cybin.pyx") + from Cython.Build import cythonize + cythonize("thriftpy2/transport/cybase.pyx") + cythonize("thriftpy2/transport/**/*.pyx") + cythonize("thriftpy2/protocol/cybin/cybin.pyx") ext_modules.append(Extension("thriftpy2.transport.cybase", ["thriftpy2/transport/cybase.c"])) @@ -106,7 +98,6 @@ "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", @@ -114,6 +105,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/oneway.thrift new/thriftpy2-0.4.20/tests/oneway.thrift --- old/thriftpy2-0.4.16/tests/oneway.thrift 1970-01-01 01:00:00.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/oneway.thrift 2024-02-28 11:00:33.000000000 +0100 @@ -0,0 +1,3 @@ +service echo { + oneway void Test(1: string req) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/parser-cases/annotations.thrift new/thriftpy2-0.4.20/tests/parser-cases/annotations.thrift --- old/thriftpy2-0.4.16/tests/parser-cases/annotations.thrift 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/parser-cases/annotations.thrift 2024-02-28 11:00:33.000000000 +0100 @@ -19,6 +19,8 @@ typedef list<i32> ( cpp.template = "std::list" ) int_linked_list +const string id = "id" (name="LANG_ID"); + struct foo { 1: i32 bar ( presence = "required" ); 2: i32 baz ( presence = "manual", cpp.use_pointer = "", ); @@ -53,3 +55,7 @@ void foo() ( foo = "bar" ) } (a.b="c") +union foo_union { + 1: optional bool abc + 2: optional i32 xyz +} (a.b="c") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/test_aio.py new/thriftpy2-0.4.20/tests/test_aio.py --- old/thriftpy2-0.4.16/tests/test_aio.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/test_aio.py 2024-02-28 11:00:33.000000000 +0100 @@ -316,14 +316,14 @@ This class should be removed when the socket_timeout argument is removed. """ - def setup(self): + def setup_method(self): # Create and apply a fresh patch for each test. self.async_sock = patch( 'thriftpy2.contrib.aio.rpc.TAsyncSocket', side_effect=RuntimeError, ).__enter__() - def teardown_(self): + def teardown_method(self): self.async_sock.__exit__() # Clean up patch @pytest.mark.asyncio @@ -348,9 +348,13 @@ is emitted (if any) and that the patch is properly applied by consuming the RuntimeError. """ - with pytest.warns(warning),\ - pytest.raises(RuntimeError): # Consume error - await make_aio_client(addressbook.AddressBookService, **kwargs) + if warning: + with pytest.warns(warning),\ + pytest.raises(RuntimeError): # Consume error + await make_aio_client(addressbook.AddressBookService, **kwargs) + else: + with pytest.raises(RuntimeError): # Consume error + await make_aio_client(addressbook.AddressBookService, **kwargs) def _given_timeout(self): """Get the timeout provided to TAsyncSocket.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/test_aio_protocol_binary.py new/thriftpy2-0.4.20/tests/test_aio_protocol_binary.py --- old/thriftpy2-0.4.16/tests/test_aio_protocol_binary.py 1970-01-01 01:00:00.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/test_aio_protocol_binary.py 2024-02-28 11:00:33.000000000 +0100 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +from io import BytesIO + +import pytest + +from thriftpy2.thrift import TType, TPayload +from thriftpy2.contrib.aio.protocol import binary as proto + + +class TItem(TPayload): + thrift_spec = { + 1: (TType.I32, "id", False), + 2: (TType.LIST, "phones", (TType.STRING), False), + } + default_spec = [("id", None), ("phones", None)] + + +class AsyncBytesIO: + def __init__(self, b): + self.b = b + + async def read(self, *args, **kwargs): + return self.b.read(*args, **kwargs) + + +@pytest.mark.asyncio +async def test_strict_decode(): + bs = AsyncBytesIO(BytesIO(b"\x00\x00\x00\x0c\x00" # there is a redundant '\x00' + b"\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c")) + with pytest.raises(UnicodeDecodeError): + await proto.read_val(bs, TType.STRING, decode_response=True, + strict_decode=True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/test_aio_protocol_compact.py new/thriftpy2-0.4.20/tests/test_aio_protocol_compact.py --- old/thriftpy2-0.4.16/tests/test_aio_protocol_compact.py 1970-01-01 01:00:00.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/test_aio_protocol_compact.py 2024-02-28 11:00:33.000000000 +0100 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +from io import BytesIO + +import pytest + +from thriftpy2.thrift import TType, TPayload +from thriftpy2.contrib.aio.protocol import compact +from test_aio_protocol_binary import AsyncBytesIO + + +class TItem(TPayload): + thrift_spec = { + 1: (TType.I32, "id", False), + 2: (TType.LIST, "phones", (TType.STRING), False), + } + default_spec = [("id", None), ("phones", None)] + + +def gen_proto(bytearray=b''): + b = AsyncBytesIO(BytesIO(bytearray)) + proto = compact.TAsyncCompactProtocol(b) + return (b, proto) + + +@pytest.mark.asyncio +async def test_strict_decode(): + b, proto = gen_proto(b'\x0c\xe4\xbd\xa0\xe5\xa5\x00' + b'\xbd\xe4\xb8\x96\xe7\x95\x8c') + proto.strict_decode = True + + with pytest.raises(UnicodeDecodeError): + await proto._read_val(TType.STRING) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/test_oneway.py new/thriftpy2-0.4.20/tests/test_oneway.py --- old/thriftpy2-0.4.16/tests/test_oneway.py 1970-01-01 01:00:00.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/test_oneway.py 2024-02-28 11:00:33.000000000 +0100 @@ -0,0 +1,32 @@ +import multiprocessing +import thriftpy2 +import time +from thriftpy2.rpc import make_client, make_server + + +class Dispatcher(object): + def Test(self, req): + print("Get req msg: %s" % req) + + assert req == "Hello!" + + +class TestOneway(object): + + oneway_thrift = thriftpy2.load("oneway.thrift") + + def setup_class(self): + ctx = multiprocessing.get_context("fork") + server = make_server(self.oneway_thrift.echo, Dispatcher(), '127.0.0.1', 6000) + self.p = ctx.Process(target=server.serve) + self.p.start() + time.sleep(1) # Wait a second for server to start. + + def teardown_class(self): + self.p.terminate() + + def test_echo(self): + req = "Hello!" + client = make_client(self.oneway_thrift.echo, '127.0.0.1', 6000) + + assert client.Test(req) == None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/test_parser.py new/thriftpy2-0.4.20/tests/test_parser.py --- old/thriftpy2-0.4.16/tests/test_parser.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/test_parser.py 2024-02-28 11:00:33.000000000 +0100 @@ -207,7 +207,7 @@ def test_e_grammer_error_at_eof(): with pytest.raises(ThriftGrammerError) as excinfo: load('parser-cases/e_grammer_error_at_eof.thrift') - assert str(excinfo.value) == 'Grammer error at EOF' + assert str(excinfo.value) == 'Grammar error at EOF' def test_e_use_thrift_reserved_keywords(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/test_protocol_binary.py new/thriftpy2-0.4.20/tests/test_protocol_binary.py --- old/thriftpy2-0.4.16/tests/test_protocol_binary.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/test_protocol_binary.py 2024-02-28 11:00:33.000000000 +0100 @@ -2,6 +2,8 @@ from io import BytesIO +import pytest + from thriftpy2._compat import u from thriftpy2.thrift import TType, TPayload from thriftpy2.utils import hexlify @@ -98,6 +100,14 @@ bs, TType.STRING, decode_response=False) +def test_strict_decode(): + bs = BytesIO(b"\x00\x00\x00\x0c\x00" # there is a redundant '\x00' + b"\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c") + with pytest.raises(UnicodeDecodeError): + proto.read_val(bs, TType.STRING, decode_response=True, + strict_decode=True) + + def test_write_message_begin(): b = BytesIO() proto.TBinaryProtocol(b).write_message_begin("test", TType.STRING, 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/test_protocol_compact.py new/thriftpy2-0.4.20/tests/test_protocol_compact.py --- old/thriftpy2-0.4.16/tests/test_protocol_compact.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/test_protocol_compact.py 2024-02-28 11:00:33.000000000 +0100 @@ -2,6 +2,8 @@ from io import BytesIO +import pytest + from thriftpy2._compat import u from thriftpy2.thrift import TType, TPayload from thriftpy2.utils import hexlify @@ -115,6 +117,15 @@ assert u('ä½ å¥½ä¸ç').encode("utf-8") == proto._read_val(TType.STRING) +def test_strict_decode(): + b, proto = gen_proto(b'\x0c\xe4\xbd\xa0\xe5\xa5\x00' + b'\xbd\xe4\xb8\x96\xe7\x95\x8c') + proto.strict_decode = True + + with pytest.raises(UnicodeDecodeError): + proto._read_val(TType.STRING) + + def test_pack_bool(): b, proto = gen_proto() proto._write_bool(True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/test_protocol_cybinary.py new/thriftpy2-0.4.20/tests/test_protocol_cybinary.py --- old/thriftpy2-0.4.16/tests/test_protocol_cybinary.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/test_protocol_cybinary.py 2024-02-28 11:00:33.000000000 +0100 @@ -147,6 +147,14 @@ b, TType.STRING, decode_response=False) +def test_strict_decode(): + bs = TCyMemoryBuffer(b"\x00\x00\x00\x0c\x00" # there is a redundant '\x00' + b"\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c") + with pytest.raises(UnicodeDecodeError): + proto.read_val(bs, TType.STRING, decode_response=True, + strict_decode=True) + + def test_write_message_begin(): trans = TCyMemoryBuffer() b = proto.TCyBinaryProtocol(trans) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/tests/test_rpc.py new/thriftpy2-0.4.20/tests/test_rpc.py --- old/thriftpy2-0.4.16/tests/test_rpc.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/tests/test_rpc.py 2024-02-28 11:00:33.000000000 +0100 @@ -250,9 +250,8 @@ def test_client_timeout(): with pytest.raises(socket.timeout): - with pytest.warns(UserWarning): # Deprecated - with client(timeout=500) as c: - c.sleep(1000) + with client(timeout=500) as c: + c.sleep(1000) def test_client_socket_timeout(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/__init__.py new/thriftpy2-0.4.20/thriftpy2/__init__.py --- old/thriftpy2-0.4.16/thriftpy2/__init__.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/__init__.py 2024-02-28 11:00:33.000000000 +0100 @@ -5,7 +5,7 @@ from .hook import install_import_hook, remove_import_hook from .parser import load, load_module, load_fp -__version__ = '0.4.16' +__version__ = '0.4.20' __python__ = sys.version_info __all__ = ["install_import_hook", "remove_import_hook", "load", "load_module", "load_fp"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/contrib/aio/client.py new/thriftpy2-0.4.20/thriftpy2/contrib/aio/client.py --- old/thriftpy2-0.4.16/thriftpy2/contrib/aio/client.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/contrib/aio/client.py 2024-02-28 11:00:33.000000000 +0100 @@ -40,7 +40,9 @@ return await self._recv(_api) async def _send(self, _api, **kwargs): - self._oprot.write_message_begin(_api, TMessageType.CALL, self._seqid) + oneway = getattr(getattr(self._service, _api + "_result"), "oneway") + msg_type = TMessageType.ONEWAY if oneway else TMessageType.CALL + self._oprot.write_message_begin(_api, msg_type, self._seqid) args = getattr(self._service, _api + "_args")() for k, v in kwargs.items(): setattr(args, k, v) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/contrib/aio/protocol/binary.py new/thriftpy2-0.4.20/thriftpy2/contrib/aio/protocol/binary.py --- old/thriftpy2-0.4.16/thriftpy2/contrib/aio/protocol/binary.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/contrib/aio/protocol/binary.py 2024-02-28 11:00:33.000000000 +0100 @@ -70,7 +70,8 @@ return k_type, v_type, sz -async def read_val(inbuf, ttype, spec=None, decode_response=True): +async def read_val(inbuf, ttype, spec=None, decode_response=True, + strict_decode=False): if ttype == TType.BOOL: return bool(unpack_i8(await inbuf.read(1))) @@ -103,7 +104,8 @@ try: return byte_payload.decode('utf-8') except UnicodeDecodeError: - pass + if strict_decode: + raise return byte_payload elif ttype == TType.SET or ttype == TType.LIST: @@ -123,7 +125,8 @@ for i in range(sz): result.append( - await read_val(inbuf, v_type, v_spec, decode_response) + await read_val(inbuf, v_type, v_spec, decode_response, + strict_decode) ) return result @@ -153,19 +156,21 @@ return {} for i in range(sz): - k_val = await read_val(inbuf, k_type, k_spec, decode_response) - v_val = await read_val(inbuf, v_type, v_spec, decode_response) + k_val = await read_val(inbuf, k_type, k_spec, decode_response, + strict_decode) + v_val = await read_val(inbuf, v_type, v_spec, decode_response, + strict_decode) result[k_val] = v_val return result elif ttype == TType.STRUCT: obj = spec() - await read_struct(inbuf, obj, decode_response) + await read_struct(inbuf, obj, decode_response, strict_decode) return obj -async def read_struct(inbuf, obj, decode_response=True): +async def read_struct(inbuf, obj, decode_response=True, strict_decode=False): while True: f_type, fid = await read_field_begin(inbuf) if f_type == TType.STOP: @@ -191,7 +196,7 @@ continue _buf = await read_val( - inbuf, f_type, f_container_spec, decode_response) + inbuf, f_type, f_container_spec, decode_response, strict_decode) setattr(obj, f_name, _buf) @@ -239,11 +244,12 @@ def __init__(self, trans, strict_read=True, strict_write=True, - decode_response=True): + decode_response=True, strict_decode=False): TAsyncProtocolBase.__init__(self, trans) self.strict_read = strict_read self.strict_write = strict_write self.decode_response = decode_response + self.strict_decode = strict_decode async def skip(self, ttype): await skip(self.trans, ttype) @@ -266,7 +272,8 @@ pass async def read_struct(self, obj): - return await read_struct(self.trans, obj, self.decode_response) + return await read_struct(self.trans, obj, self.decode_response, + self.strict_decode) def write_struct(self, obj): write_val(self.trans, TType.STRUCT, obj) @@ -274,15 +281,17 @@ class TAsyncBinaryProtocolFactory(object): def __init__(self, strict_read=True, strict_write=True, - decode_response=True): + decode_response=True, strict_decode=False): self.strict_read = strict_read self.strict_write = strict_write self.decode_response = decode_response + self.strict_decode = strict_decode def get_protocol(self, trans): return TAsyncBinaryProtocol( trans, self.strict_read, self.strict_write, - self.decode_response + self.decode_response, + self.strict_decode, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/contrib/aio/protocol/compact.py new/thriftpy2-0.4.20/thriftpy2/contrib/aio/protocol/compact.py --- old/thriftpy2-0.4.16/thriftpy2/contrib/aio/protocol/compact.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/contrib/aio/protocol/compact.py 2024-02-28 11:00:33.000000000 +0100 @@ -145,7 +145,8 @@ try: byte_payload = byte_payload.decode('utf-8') except UnicodeDecodeError: - pass + if self.strict_decode: + raise return byte_payload async def _read_bool(self): @@ -305,11 +306,13 @@ class TAsyncCompactProtocolFactory(object): - def __init__(self, decode_response=True): + def __init__(self, decode_response=True, strict_decode=False): self.decode_response = decode_response + self.strict_decode = strict_decode def get_protocol(self, trans): return TAsyncCompactProtocol( trans, decode_response=self.decode_response, + strict_decode=self.strict_decode, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/contrib/aio/socket.py new/thriftpy2-0.4.20/thriftpy2/contrib/aio/socket.py --- old/thriftpy2-0.4.16/thriftpy2/contrib/aio/socket.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/contrib/aio/socket.py 2024-02-28 11:00:33.000000000 +0100 @@ -292,15 +292,25 @@ async def accept(self, callback): server = await self.sock_factory( - lambda reader, writer: asyncio.wait_for( - callback(StreamHandler(reader, writer)), - self.client_timeout - ), + self._create_client_connected_cb(callback), sock=self.raw_sock, ssl=self.ssl_context ) return server + def _create_client_connected_cb(self, callback): + + async def client_connected_cb(reader, writer): + try: + await asyncio.wait_for( + callback(StreamHandler(reader, writer)), + self.client_timeout + ) + except asyncio.exceptions.TimeoutError: + writer.close() + + return client_connected_cb + def close(self): if not self.raw_sock: return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/hook.py new/thriftpy2-0.4.20/thriftpy2/hook.py --- old/thriftpy2-0.4.16/thriftpy2/hook.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/hook.py 2024-02-28 11:00:33.000000000 +0100 @@ -7,21 +7,44 @@ from .parser import load_module -class ThriftImporter(object): - def __init__(self, extension="_thrift"): - self.extension = extension - - def __eq__(self, other): - return self.__class__.__module__ == other.__class__.__module__ and \ - self.__class__.__name__ == other.__class__.__name__ and \ - self.extension == other.extension - - def find_module(self, fullname, path=None): - if fullname.endswith(self.extension): - return self +# TODO: The load process does not compatible with Python standard, e.g., if the +# specified thrift file does not exists, it raises FileNotFoundError, and skiped +# the other meta finders in the sys.meta_path. +if sys.version_info >= (3, 4): + import importlib.abc + import importlib.util + + class ThriftImporter(importlib.abc.MetaPathFinder): + def __init__(self, extension="_thrift"): + self.extension = extension + + def find_spec(self, fullname, path, target=None): + if not fullname.endswith(self.extension): + return None + return importlib.util.spec_from_loader(fullname, + ThriftLoader(fullname)) + + + class ThriftLoader(importlib.abc.Loader): + def __init__(self, fullname): + self.fullname = fullname + + def create_module(self, spec): + return load_module(self.fullname) + + def exec_module(self, module): + pass +else: + class ThriftImporter(object): + def __init__(self, extension="_thrift"): + self.extension = extension + + def find_module(self, fullname, path=None): + if fullname.endswith(self.extension): + return self - def load_module(self, fullname): - return load_module(fullname) + def load_module(self, fullname): + return load_module(fullname) _imp = ThriftImporter() @@ -29,9 +52,9 @@ def install_import_hook(): global _imp - sys.meta_path[:] = [x for x in sys.meta_path if _imp != x] + [_imp] + sys.meta_path[:] = [x for x in sys.meta_path if _imp is not x] + [_imp] def remove_import_hook(): global _imp - sys.meta_path[:] = [x for x in sys.meta_path if _imp != x] + sys.meta_path[:] = [x for x in sys.meta_path if _imp is not x] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/parser/__init__.py new/thriftpy2-0.4.20/thriftpy2/parser/__init__.py --- old/thriftpy2-0.4.16/thriftpy2/parser/__init__.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/parser/__init__.py 2024-02-28 11:00:33.000000000 +0100 @@ -34,7 +34,7 @@ """ real_module = bool(module_name) thrift = parse(path, module_name, include_dirs=include_dirs, - include_dir=include_dir) + include_dir=include_dir, encoding=encoding) if incomplete_type: fill_incomplete_ttype(thrift, thrift) if real_module: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/parser/exc.py new/thriftpy2-0.4.20/thriftpy2/parser/exc.py --- old/thriftpy2-0.4.16/thriftpy2/parser/exc.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/parser/exc.py 2024-02-28 11:00:33.000000000 +0100 @@ -2,6 +2,9 @@ from __future__ import absolute_import +import sys +from warnings import warn + class ThriftParserError(Exception): pass @@ -11,5 +14,16 @@ pass -class ThriftGrammerError(ThriftParserError): +class ThriftGrammarError(ThriftParserError): pass + + +if sys.version_info >= (3, 7): + def __getattr__(name): + if name == "ThriftGrammerError": + warn("'ThriftGrammerError' is a typo of 'ThriftGrammarError'", DeprecationWarning) + return ThriftGrammarError + + raise AttributeError("module %r has no attribute %r" % (__name__, name)) +else: + ThriftGrammerError = ThriftGrammarError diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/parser/parser.py new/thriftpy2-0.4.20/thriftpy2/parser/parser.py --- old/thriftpy2-0.4.16/thriftpy2/parser/parser.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/parser/parser.py 2024-02-28 11:00:33.000000000 +0100 @@ -13,15 +13,18 @@ import types from ply import lex, yacc from .lexer import * # noqa -from .exc import ThriftParserError, ThriftGrammerError +from .exc import ThriftParserError, ThriftGrammarError from thriftpy2._compat import urlopen, urlparse, PY3 from ..thrift import gen_init, TType, TPayload, TException +if not PY3: + from io import open + def p_error(p): if p is None: - raise ThriftGrammerError('Grammer error at EOF') - raise ThriftGrammerError('Grammer error %r at line %d' % + raise ThriftGrammarError('Grammar error at EOF') + raise ThriftGrammarError('Grammar error %r at line %d' % (p.value, p.lineno)) @@ -104,8 +107,8 @@ def p_const(p): - '''const : CONST field_type IDENTIFIER '=' const_value - | CONST field_type IDENTIFIER '=' const_value sep''' + '''const : CONST field_type IDENTIFIER '=' const_value type_annotations + | CONST field_type IDENTIFIER '=' const_value type_annotations sep''' try: val = _cast(p[2], p.lineno(3))(p[5]) @@ -226,7 +229,7 @@ def p_union(p): - '''union : seen_union '{' field_seq '}' ''' + '''union : seen_union '{' field_seq '}' type_annotations''' val = _fill_in_struct(p[1], p[3]) _add_thrift_meta('unions', val) @@ -573,7 +576,7 @@ with open(urlparse(path).netloc + urlparse(path).path) as fh: data = fh.read() elif len(url_scheme) <= 1: - with open(path) as fh: + with open(path, encoding=encoding) as fh: data = fh.read() elif url_scheme in ('http', 'https'): data = urlopen(path).read() @@ -582,8 +585,11 @@ 'with path in protocol \'{}\''.format( url_scheme)) - if PY3 and isinstance(data, bytes): - data = data.decode(encoding) + if PY3: + if isinstance(data, bytes): + data = data.decode(encoding) + else: + data = data.encode(encoding) if module_name is not None and not module_name.endswith('_thrift'): raise ThriftParserError('thriftpy2 can only generate module with ' @@ -661,7 +667,7 @@ meta = getattr(thrift, '__thrift_meta__') if key != 'consts' and val.__name__ in [x.__name__ for x in meta[key]]: - raise ThriftGrammerError(('\'%s\' type is already defined in ' + raise ThriftGrammarError(('\'%s\' type is already defined in ' '\'%s\'') % (val.__name__, key)) meta[key].append(val) @@ -863,7 +869,7 @@ for field in fields: if field[0] in thrift_spec or field[3] in _tspec: - raise ThriftGrammerError(('\'%d:%s\' field identifier/name has ' + raise ThriftGrammarError(('\'%d:%s\' field identifier/name has ' 'already been used') % (field[0], field[3])) ttype = field[2] @@ -895,7 +901,7 @@ for func in funcs: func_name = func[2] if func_name in thrift_services: - raise ThriftGrammerError(('\'%s\' function is already defined in ' + raise ThriftGrammarError(('\'%s\' function is already defined in ' 'service \'%s\'') % (func_name, name)) # args payload cls diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/protocol/binary.py new/thriftpy2-0.4.20/thriftpy2/protocol/binary.py --- old/thriftpy2-0.4.16/thriftpy2/protocol/binary.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/protocol/binary.py 2024-02-28 11:00:33.000000000 +0100 @@ -215,7 +215,8 @@ return k_type, v_type, sz -def read_val(inbuf, ttype, spec=None, decode_response=True): +def read_val(inbuf, ttype, spec=None, decode_response=True, + strict_decode=False): if ttype == TType.BOOL: return bool(unpack_i8(inbuf.read(1))) @@ -248,7 +249,8 @@ try: return byte_payload.decode('utf-8') except UnicodeDecodeError: - pass + if strict_decode: + raise return byte_payload elif ttype == TType.SET or ttype == TType.LIST: @@ -267,7 +269,8 @@ return [] for i in range(sz): - result.append(read_val(inbuf, v_type, v_spec, decode_response)) + result.append(read_val(inbuf, v_type, v_spec, decode_response, + strict_decode)) return result elif ttype == TType.MAP: @@ -296,19 +299,21 @@ return {} for i in range(sz): - k_val = read_val(inbuf, k_type, k_spec, decode_response) - v_val = read_val(inbuf, v_type, v_spec, decode_response) + k_val = read_val(inbuf, k_type, k_spec, decode_response, + strict_decode) + v_val = read_val(inbuf, v_type, v_spec, decode_response, + strict_decode) result[k_val] = v_val return result elif ttype == TType.STRUCT: obj = spec() - read_struct(inbuf, obj, decode_response) + read_struct(inbuf, obj, decode_response, strict_decode) return obj -def read_struct(inbuf, obj, decode_response=True): +def read_struct(inbuf, obj, decode_response=True, strict_decode=False): while True: f_type, fid = read_field_begin(inbuf) if f_type == TType.STOP: @@ -334,7 +339,8 @@ continue setattr(obj, f_name, - read_val(inbuf, f_type, f_container_spec, decode_response)) + read_val(inbuf, f_type, f_container_spec, decode_response, + strict_decode)) def skip(inbuf, ftype): @@ -380,11 +386,12 @@ def __init__(self, trans, strict_read=True, strict_write=True, - decode_response=True): + decode_response=True, strict_decode=False): TProtocolBase.__init__(self, trans) self.strict_read = strict_read self.strict_write = strict_write self.decode_response = decode_response + self.strict_decode = strict_decode def skip(self, ttype): skip(self.trans, ttype) @@ -405,7 +412,8 @@ pass def read_struct(self, obj): - return read_struct(self.trans, obj, self.decode_response) + return read_struct(self.trans, obj, self.decode_response, + self.strict_decode) def write_struct(self, obj): write_val(self.trans, TType.STRUCT, obj) @@ -413,12 +421,13 @@ class TBinaryProtocolFactory(object): def __init__(self, strict_read=True, strict_write=True, - decode_response=True): + decode_response=True, strict_decode=False): self.strict_read = strict_read self.strict_write = strict_write self.decode_response = decode_response + self.strict_decode = strict_decode def get_protocol(self, trans): return TBinaryProtocol(trans, self.strict_read, self.strict_write, - self.decode_response) + self.decode_response, self.strict_decode) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/protocol/compact.py new/thriftpy2-0.4.20/thriftpy2/protocol/compact.py --- old/thriftpy2-0.4.16/thriftpy2/protocol/compact.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/protocol/compact.py 2024-02-28 11:00:33.000000000 +0100 @@ -129,13 +129,14 @@ TYPE_BITS = 0x07 TYPE_SHIFT_AMOUNT = 5 - def __init__(self, trans, decode_response=True): + def __init__(self, trans, decode_response=True, strict_decode=False): TProtocolBase.__init__(self, trans) self._last_fid = 0 self._bool_fid = None self._bool_value = None self._structs = [] self.decode_response = decode_response + self.strict_decode = strict_decode def _get_ttype(self, byte): return TTYPES[byte & 0x0f] @@ -245,7 +246,8 @@ try: byte_payload = byte_payload.decode('utf-8') except UnicodeDecodeError: - pass + if self.strict_decode: + raise return byte_payload def _read_bool(self): @@ -586,8 +588,10 @@ class TCompactProtocolFactory(object): - def __init__(self, decode_response=True): + def __init__(self, decode_response=True, strict_decode=False): self.decode_response = decode_response + self.strict_decode = strict_decode def get_protocol(self, trans): - return TCompactProtocol(trans, decode_response=self.decode_response) + return TCompactProtocol(trans, decode_response=self.decode_response, + strict_decode=self.strict_decode) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/protocol/cybin/cybin.pyx new/thriftpy2-0.4.20/thriftpy2/protocol/cybin/cybin.pyx --- old/thriftpy2-0.4.16/thriftpy2/protocol/cybin/cybin.pyx 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/protocol/cybin/cybin.pyx 2024-02-28 11:00:33.000000000 +0100 @@ -170,7 +170,8 @@ c_write_val(buf, v_type, v, v_spec) -cdef inline read_struct(CyTransportBase buf, obj, decode_response=True): +cdef inline read_struct(CyTransportBase buf, obj, decode_response=True, + strict_decode=False): cdef dict field_specs = obj.thrift_spec cdef int fid cdef TType field_type, ttype @@ -199,7 +200,8 @@ else: spec = field_spec[2] - setattr(obj, name, c_read_val(buf, ttype, spec, decode_response)) + setattr(obj, name, c_read_val(buf, ttype, spec, decode_response, + strict_decode)) return obj @@ -251,16 +253,19 @@ return py_data -cdef inline c_read_string(CyTransportBase buf, int32_t size): +cdef inline c_read_string(CyTransportBase buf, int32_t size, + strict_decode=False): py_data = c_read_binary(buf, size) try: return (<char *>py_data)[:size].decode("utf-8") except: # noqa + if strict_decode: + raise return py_data cdef c_read_val(CyTransportBase buf, TType ttype, spec=None, - decode_response=True): + decode_response=True, strict_decode=False): cdef int size cdef int64_t n cdef TType v_type, k_type, orig_type, orig_key_type @@ -291,7 +296,7 @@ elif ttype == T_STRING: size = read_i32(buf) if decode_response: - return c_read_string(buf, size) + return c_read_string(buf, size, strict_decode) else: return c_read_binary(buf, size) @@ -311,7 +316,7 @@ skip(buf, orig_type) return [] - return [c_read_val(buf, v_type, v_spec, decode_response) + return [c_read_val(buf, v_type, v_spec, decode_response, strict_decode) for _ in range(size)] elif ttype == T_MAP: @@ -345,13 +350,13 @@ return {} return { - c_read_val(buf, k_type, k_spec, decode_response): - c_read_val(buf, v_type, v_spec, decode_response) + c_read_val(buf, k_type, k_spec, decode_response, strict_decode): + c_read_val(buf, v_type, v_spec, decode_response, strict_decode) for _ in range(size) } elif ttype == T_STRUCT: - return read_struct(buf, spec(), decode_response) + return read_struct(buf, spec(), decode_response, strict_decode) cdef c_write_val(CyTransportBase buf, TType ttype, val, spec=None): @@ -432,8 +437,9 @@ skip(buf, f_type) -def read_val(CyTransportBase buf, TType ttype, decode_response=True): - return c_read_val(buf, ttype, None, decode_response) +def read_val(CyTransportBase buf, TType ttype, decode_response=True, + strict_decode=False): + return c_read_val(buf, ttype, None, decode_response, strict_decode) def write_val(CyTransportBase buf, TType ttype, val, spec=None): @@ -445,13 +451,15 @@ cdef public bool strict_read cdef public bool strict_write cdef public bool decode_response + cdef public bool strict_decode def __init__(self, trans, strict_read=True, strict_write=True, - decode_response=True): + decode_response=True, strict_decode=False): self.trans = trans self.strict_read = strict_read self.strict_write = strict_write self.decode_response = decode_response + self.strict_decode = strict_decode def skip(self, ttype): skip(self.trans, <TType>(ttype)) @@ -498,7 +506,8 @@ def read_struct(self, obj): try: - return read_struct(self.trans, obj, self.decode_response) + return read_struct(self.trans, obj, self.decode_response, + self.strict_decode) except Exception: self.trans.clean() raise @@ -513,11 +522,13 @@ class TCyBinaryProtocolFactory(object): def __init__(self, strict_read=True, strict_write=True, - decode_response=True): + decode_response=True, strict_decode=False): self.strict_read = strict_read self.strict_write = strict_write self.decode_response = decode_response + self.strict_decode = strict_decode def get_protocol(self, trans): return TCyBinaryProtocol( - trans, self.strict_read, self.strict_write, self.decode_response) + trans, self.strict_read, self.strict_write, self.decode_response, + self.strict_decode) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/thrift.py new/thriftpy2-0.4.20/thriftpy2/thrift.py --- old/thriftpy2-0.4.16/thriftpy2/thrift.py 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/thrift.py 2024-02-28 11:00:33.000000000 +0100 @@ -219,7 +219,9 @@ return self._recv(_api) def _send(self, _api, **kwargs): - self._oprot.write_message_begin(_api, TMessageType.CALL, self._seqid) + oneway = getattr(getattr(self._service, _api + "_result"), "oneway") + msg_type = TMessageType.ONEWAY if oneway else TMessageType.CALL + self._oprot.write_message_begin(_api, msg_type, self._seqid) args = getattr(self._service, _api + "_args")() for k, v in kwargs.items(): setattr(args, k, v) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thriftpy2-0.4.16/thriftpy2/transport/cybase.pyx new/thriftpy2-0.4.20/thriftpy2/transport/cybase.pyx --- old/thriftpy2-0.4.16/thriftpy2/transport/cybase.pyx 2022-11-15 10:41:16.000000000 +0100 +++ new/thriftpy2-0.4.20/thriftpy2/transport/cybase.pyx 2024-02-28 11:00:33.000000000 +0100 @@ -87,7 +87,7 @@ if min_size <= self.buf_size: return 0 - cdef int multiples = min_size / self.buf_size + cdef int multiples = min_size // self.buf_size if min_size % self.buf_size != 0: multiples += 1