Skip to content

Commit 7921456

Browse files
authored
Make vertica_python.errors classes (un)picklable (#374)
1 parent be0c9a3 commit 7921456

2 files changed

Lines changed: 61 additions & 0 deletions

File tree

vertica_python/errors.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,17 @@ def one_line_sql(self):
137137
else:
138138
return ''
139139

140+
def __reduce__(self):
141+
# Workaround to make these exception instances (un)picklable. This must
142+
# be redefined by any subclass that changes the signature of __init__
143+
#
144+
# This workaround applies to python3. https://bugs.python.org/issue37489
145+
return (
146+
type(self),
147+
(self.error_response, self.sql),
148+
self.__dict__,
149+
)
150+
140151
@property
141152
def _notice_attrs(self):
142153
# provided for _NoticeResponseAttrMixin
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright (c) 2018-2020 Micro Focus or one of its affiliates.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
from __future__ import print_function, division, absolute_import
17+
18+
from .base import VerticaPythonUnitTestCase
19+
from ...errors import VerticaSyntaxError
20+
from ...vertica.messages.backend_messages.error_response import ErrorResponse
21+
22+
import pickle
23+
24+
# Using a subclass of ErrorResponse for this test, to avoid the complexity of
25+
# creating an ErrorResponse object. At the time of writing, ErrorResponse and
26+
# other BackendMessage instances can only be created from server-provided data.
27+
#
28+
# This subclass allows for simpler instantiation without binding to any details
29+
# of server data serialization, a la NoticeResponseAttrMixin and NoticeResponse
30+
class MockErrorResponse(ErrorResponse):
31+
def __init__(self):
32+
# does NOT call super
33+
self._notice_attrs = {}
34+
35+
def error_message(self):
36+
return "Manufactured error message for testing"
37+
38+
class ErrorsTestCase(VerticaPythonUnitTestCase):
39+
def test_pickling(self):
40+
err_response = MockErrorResponse()
41+
sql = "select 1;"
42+
exc = VerticaSyntaxError(err_response, sql)
43+
44+
serde = pickle.loads(pickle.dumps(exc))
45+
46+
assert isinstance(serde, VerticaSyntaxError)
47+
assert str(serde) == str(exc)
48+
assert isinstance(serde.error_response, MockErrorResponse)
49+
assert serde.error_response.error_message() == err_response.error_message()
50+
assert serde.sql == exc.sql

0 commit comments

Comments
 (0)