testgres 1.12.2__tar.gz → 1.13.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {testgres-1.12.2 → testgres-1.13.1}/LICENSE +1 -1
- {testgres-1.12.2/testgres.egg-info → testgres-1.13.1}/PKG-INFO +21 -15
- {testgres-1.12.2 → testgres-1.13.1}/README.md +3 -1
- testgres-1.13.1/pyproject.toml +61 -0
- testgres-1.13.1/setup.cfg +4 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/__init__.py +4 -1
- testgres-1.13.1/src/exceptions.py +300 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/node.py +295 -262
- {testgres-1.12.2 → testgres-1.13.1}/src/node_app.py +2 -2
- testgres-1.13.1/src/raise_error.py +85 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/utils.py +142 -0
- {testgres-1.12.2 → testgres-1.13.1/testgres.egg-info}/PKG-INFO +21 -15
- {testgres-1.12.2 → testgres-1.13.1}/testgres.egg-info/SOURCES.txt +4 -9
- {testgres-1.12.2 → testgres-1.13.1}/testgres.egg-info/requires.txt +1 -1
- {testgres-1.12.2 → testgres-1.13.1}/tests/test_os_ops_remote.py +2 -1
- testgres-1.13.1/tests/test_raise_error.py +100 -0
- {testgres-1.12.2 → testgres-1.13.1}/tests/test_testgres_common.py +809 -38
- {testgres-1.12.2 → testgres-1.13.1}/tests/test_testgres_local.py +7 -2
- testgres-1.12.2/MANIFEST.in +0 -8
- testgres-1.12.2/setup.cfg +0 -11
- testgres-1.12.2/setup.py +0 -45
- testgres-1.12.2/src/exceptions.py +0 -71
- testgres-1.12.2/tests/__init__.py +0 -0
- testgres-1.12.2/tests/conftest.py +0 -1141
- testgres-1.12.2/tests/helpers/__init__.py +0 -0
- testgres-1.12.2/tests/helpers/global_data.py +0 -78
- testgres-1.12.2/tests/helpers/run_conditions.py +0 -12
- {testgres-1.12.2 → testgres-1.13.1}/src/api.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/backup.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/cache.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/config.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/connection.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/consts.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/decorators.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/defaults.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/enums.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/impl/port_manager__generic.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/impl/port_manager__this_host.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/logger.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/port_manager.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/pubsub.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/src/standby.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/testgres.egg-info/dependency_links.txt +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/testgres.egg-info/top_level.txt +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/tests/test_config.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/tests/test_os_ops_common.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/tests/test_os_ops_local.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/tests/test_testgres_remote.py +0 -0
- {testgres-1.12.2 → testgres-1.13.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
testgres is released under the PostgreSQL License, a liberal Open Source license, similar to the BSD or MIT licenses.
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2016-
|
|
3
|
+
Copyright (c) 2016-2026, Postgres Professional
|
|
4
4
|
|
|
5
5
|
Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies.
|
|
6
6
|
|
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: testgres
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.13.1
|
|
4
4
|
Summary: Testing utility for PostgreSQL and its extensions
|
|
5
|
-
|
|
6
|
-
Author: Postgres Professional
|
|
7
|
-
Author-email: testgres@postgrespro.ru
|
|
5
|
+
Author-email: Postgres Professional <testgres@postgrespro.ru>
|
|
8
6
|
License: PostgreSQL
|
|
7
|
+
Project-URL: HomePage, https://github.com/postgrespro/testgres
|
|
9
8
|
Keywords: test,testing,postgresql
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Operating System :: Unix
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Topic :: Software Development :: Testing
|
|
22
|
+
Requires-Python: >=3.7.17
|
|
10
23
|
Description-Content-Type: text/markdown
|
|
11
24
|
License-File: LICENSE
|
|
12
25
|
Requires-Dist: pg8000
|
|
@@ -14,21 +27,14 @@ Requires-Dist: port-for>=0.4
|
|
|
14
27
|
Requires-Dist: six>=1.9.0
|
|
15
28
|
Requires-Dist: psutil
|
|
16
29
|
Requires-Dist: packaging
|
|
17
|
-
Requires-Dist: testgres.os_ops<
|
|
18
|
-
Dynamic: author
|
|
19
|
-
Dynamic: author-email
|
|
20
|
-
Dynamic: description
|
|
21
|
-
Dynamic: description-content-type
|
|
22
|
-
Dynamic: home-page
|
|
23
|
-
Dynamic: keywords
|
|
24
|
-
Dynamic: license
|
|
30
|
+
Requires-Dist: testgres.os_ops<3.0.0,>=2.0.0
|
|
25
31
|
Dynamic: license-file
|
|
26
|
-
Dynamic: requires-dist
|
|
27
|
-
Dynamic: summary
|
|
28
32
|
|
|
29
33
|
[](https://travis-ci.com/github/postgrespro/testgres)
|
|
30
34
|
[](https://codecov.io/gh/postgrespro/testgres)
|
|
31
|
-
[](https://badge.fury.io/py/testgres)
|
|
35
|
+
[](https://badge.fury.io/py/testgres)
|
|
36
|
+
[](https://pypi.org/project/testgres)
|
|
37
|
+
[](https://pypi.org/project/testgres)
|
|
32
38
|
|
|
33
39
|
[Documentation](https://postgrespro.github.io/testgres/)
|
|
34
40
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
[](https://travis-ci.com/github/postgrespro/testgres)
|
|
2
2
|
[](https://codecov.io/gh/postgrespro/testgres)
|
|
3
|
-
[](https://badge.fury.io/py/testgres)
|
|
3
|
+
[](https://badge.fury.io/py/testgres)
|
|
4
|
+
[](https://pypi.org/project/testgres)
|
|
5
|
+
[](https://pypi.org/project/testgres)
|
|
4
6
|
|
|
5
7
|
[Documentation](https://postgrespro.github.io/testgres/)
|
|
6
8
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[tool.setuptools.package-dir]
|
|
6
|
+
"testgres" = "src"
|
|
7
|
+
|
|
8
|
+
[tool.flake8]
|
|
9
|
+
extend-ignore = ["E501"]
|
|
10
|
+
exclude = [".git", "__pycache__", "env", "venv"]
|
|
11
|
+
|
|
12
|
+
[project]
|
|
13
|
+
name = "testgres"
|
|
14
|
+
version = "1.13.1"
|
|
15
|
+
|
|
16
|
+
description = "Testing utility for PostgreSQL and its extensions"
|
|
17
|
+
readme = "README.md"
|
|
18
|
+
|
|
19
|
+
# [2026-01-05]
|
|
20
|
+
# This old format is used to ensure compatibility with Python 3.7.
|
|
21
|
+
license = {text = "PostgreSQL"}
|
|
22
|
+
|
|
23
|
+
authors = [
|
|
24
|
+
{name = "Postgres Professional", email = "testgres@postgrespro.ru"},
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
keywords = [
|
|
28
|
+
'test',
|
|
29
|
+
'testing',
|
|
30
|
+
'postgresql',
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
requires-python = ">=3.7.17"
|
|
34
|
+
|
|
35
|
+
classifiers = [
|
|
36
|
+
"Intended Audience :: Developers",
|
|
37
|
+
"Operating System :: Unix",
|
|
38
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
39
|
+
"Programming Language :: Python :: 3.7",
|
|
40
|
+
"Programming Language :: Python :: 3.8",
|
|
41
|
+
"Programming Language :: Python :: 3.9",
|
|
42
|
+
"Programming Language :: Python :: 3.10",
|
|
43
|
+
"Programming Language :: Python :: 3.11",
|
|
44
|
+
"Programming Language :: Python :: 3.12",
|
|
45
|
+
"Programming Language :: Python :: 3.13",
|
|
46
|
+
"Programming Language :: Python :: 3.14",
|
|
47
|
+
"Topic :: Software Development :: Libraries",
|
|
48
|
+
"Topic :: Software Development :: Testing",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
dependencies = [
|
|
52
|
+
"pg8000",
|
|
53
|
+
"port-for>=0.4",
|
|
54
|
+
"six>=1.9.0",
|
|
55
|
+
"psutil",
|
|
56
|
+
"packaging",
|
|
57
|
+
"testgres.os_ops>=2.0.0,<3.0.0",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[project.urls]
|
|
61
|
+
"HomePage" = "https://github.com/postgrespro/testgres"
|
|
@@ -19,6 +19,7 @@ from .exceptions import \
|
|
|
19
19
|
TestgresException, \
|
|
20
20
|
ExecUtilException, \
|
|
21
21
|
QueryException, \
|
|
22
|
+
QueryTimeoutException, \
|
|
22
23
|
TimeoutException, \
|
|
23
24
|
CatchUpException, \
|
|
24
25
|
StartNodeException, \
|
|
@@ -61,7 +62,9 @@ __all__ = [
|
|
|
61
62
|
"NodeBackup", "testgres_config",
|
|
62
63
|
"TestgresConfig", "configure_testgres", "scoped_config", "push_config", "pop_config",
|
|
63
64
|
"NodeConnection", "DatabaseError", "InternalError", "ProgrammingError", "OperationalError",
|
|
64
|
-
"TestgresException", "ExecUtilException", "QueryException",
|
|
65
|
+
"TestgresException", "ExecUtilException", "QueryException",
|
|
66
|
+
QueryTimeoutException.__name__,
|
|
67
|
+
"TimeoutException", "CatchUpException", "StartNodeException", "InitNodeException", "BackupException", "InvalidOperationException",
|
|
65
68
|
"XLogMethod", "IsolationLevel", "NodeStatus", "ProcessType", "DumpFormat",
|
|
66
69
|
NodeApp.__name__,
|
|
67
70
|
PostgresNode.__name__,
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
import six
|
|
4
|
+
import typing
|
|
5
|
+
|
|
6
|
+
from testgres.operations.exceptions import TestgresException
|
|
7
|
+
from testgres.operations.exceptions import ExecUtilException
|
|
8
|
+
from testgres.operations.exceptions import InvalidOperationException
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PortForException(TestgresException):
|
|
12
|
+
_message: typing.Optional[str]
|
|
13
|
+
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
message: typing.Optional[str] = None,
|
|
17
|
+
):
|
|
18
|
+
assert message is None or type(message) == str # noqa: E721
|
|
19
|
+
super().__init__(message)
|
|
20
|
+
self._message = message
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def message(self) -> str:
|
|
25
|
+
assert self._message is None or type(self._message) == str # noqa: E721
|
|
26
|
+
if self._message is None:
|
|
27
|
+
return ""
|
|
28
|
+
return self._message
|
|
29
|
+
|
|
30
|
+
def __repr__(self) -> str:
|
|
31
|
+
args = []
|
|
32
|
+
|
|
33
|
+
if self._message is not None:
|
|
34
|
+
args.append(("message", self._message))
|
|
35
|
+
|
|
36
|
+
result = "{}(".format(type(self).__name__)
|
|
37
|
+
sep = ""
|
|
38
|
+
for a in args:
|
|
39
|
+
result += sep + a[0] + "=" + repr(a[1])
|
|
40
|
+
sep = ", "
|
|
41
|
+
continue
|
|
42
|
+
result += ")"
|
|
43
|
+
return result
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@six.python_2_unicode_compatible
|
|
47
|
+
class QueryException(TestgresException):
|
|
48
|
+
_description: typing.Optional[str]
|
|
49
|
+
_query: typing.Optional[str]
|
|
50
|
+
|
|
51
|
+
def __init__(
|
|
52
|
+
self,
|
|
53
|
+
message: typing.Optional[str] = None,
|
|
54
|
+
query: typing.Optional[str] = None
|
|
55
|
+
):
|
|
56
|
+
assert message is None or type(message) == str # noqa: E721
|
|
57
|
+
assert query is None or type(query) == str # noqa: E721
|
|
58
|
+
|
|
59
|
+
super().__init__(message)
|
|
60
|
+
|
|
61
|
+
self._description = message
|
|
62
|
+
self._query = query
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def message(self) -> str:
|
|
67
|
+
assert self._description is None or type(self._description) == str # noqa: E721
|
|
68
|
+
assert self._query is None or type(self._query) == str # noqa: E721
|
|
69
|
+
|
|
70
|
+
msg = []
|
|
71
|
+
|
|
72
|
+
if self._description:
|
|
73
|
+
msg.append(self._description)
|
|
74
|
+
|
|
75
|
+
if self._query:
|
|
76
|
+
msg.append(u'Query: {}'.format(self._query))
|
|
77
|
+
|
|
78
|
+
r = six.text_type('\n').join(msg)
|
|
79
|
+
assert type(r) == str # noqa: E721
|
|
80
|
+
return r
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def description(self) -> typing.Optional[str]:
|
|
84
|
+
assert self._description is None or type(self._description) == str # noqa: E721
|
|
85
|
+
return self._description
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def query(self) -> typing.Optional[str]:
|
|
89
|
+
assert self._query is None or type(self._query) == str # noqa: E721
|
|
90
|
+
return self._query
|
|
91
|
+
|
|
92
|
+
def __repr__(self) -> str:
|
|
93
|
+
args = []
|
|
94
|
+
|
|
95
|
+
if self._description is not None:
|
|
96
|
+
args.append(("message", self._description))
|
|
97
|
+
|
|
98
|
+
if self._query is not None:
|
|
99
|
+
args.append(("query", self._query))
|
|
100
|
+
|
|
101
|
+
result = "{}(".format(type(self).__name__)
|
|
102
|
+
sep = ""
|
|
103
|
+
for a in args:
|
|
104
|
+
result += sep + a[0] + "=" + repr(a[1])
|
|
105
|
+
sep = ", "
|
|
106
|
+
continue
|
|
107
|
+
result += ")"
|
|
108
|
+
return result
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class QueryTimeoutException(QueryException):
|
|
112
|
+
def __init__(
|
|
113
|
+
self,
|
|
114
|
+
message: typing.Optional[str] = None,
|
|
115
|
+
query: typing.Optional[str] = None
|
|
116
|
+
):
|
|
117
|
+
assert message is None or type(message) == str # noqa: E721
|
|
118
|
+
assert query is None or type(query) == str # noqa: E721
|
|
119
|
+
|
|
120
|
+
super().__init__(message, query)
|
|
121
|
+
return
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# [2026-01-10] To backward compatibility.
|
|
125
|
+
TimeoutException = QueryTimeoutException
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# [2026-01-10] It inherits TestgresException now, not QueryException
|
|
129
|
+
class CatchUpException(TestgresException):
|
|
130
|
+
_message: typing.Optional[str]
|
|
131
|
+
|
|
132
|
+
def __init__(
|
|
133
|
+
self,
|
|
134
|
+
message: typing.Optional[str] = None,
|
|
135
|
+
):
|
|
136
|
+
assert message is None or type(message) == str # noqa: E721
|
|
137
|
+
super().__init__(message)
|
|
138
|
+
self._message = message
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def message(self) -> str:
|
|
143
|
+
assert self._message is None or type(self._message) == str # noqa: E721
|
|
144
|
+
if self._message is None:
|
|
145
|
+
return ""
|
|
146
|
+
return self._message
|
|
147
|
+
|
|
148
|
+
def __repr__(self) -> str:
|
|
149
|
+
args = []
|
|
150
|
+
|
|
151
|
+
if self._message is not None:
|
|
152
|
+
args.append(("message", self._message))
|
|
153
|
+
|
|
154
|
+
result = "{}(".format(type(self).__name__)
|
|
155
|
+
sep = ""
|
|
156
|
+
for a in args:
|
|
157
|
+
result += sep + a[0] + "=" + repr(a[1])
|
|
158
|
+
sep = ", "
|
|
159
|
+
continue
|
|
160
|
+
result += ")"
|
|
161
|
+
return result
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@six.python_2_unicode_compatible
|
|
165
|
+
class StartNodeException(TestgresException):
|
|
166
|
+
_description: typing.Optional[str]
|
|
167
|
+
_files: typing.Optional[typing.Iterable]
|
|
168
|
+
|
|
169
|
+
def __init__(
|
|
170
|
+
self,
|
|
171
|
+
message: typing.Optional[str] = None,
|
|
172
|
+
files: typing.Optional[typing.Iterable] = None
|
|
173
|
+
):
|
|
174
|
+
assert message is None or type(message) == str # noqa: E721
|
|
175
|
+
assert files is None or isinstance(files, typing.Iterable)
|
|
176
|
+
|
|
177
|
+
super().__init__(message)
|
|
178
|
+
|
|
179
|
+
self._description = message
|
|
180
|
+
self._files = files
|
|
181
|
+
return
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def message(self) -> str:
|
|
185
|
+
assert self._description is None or type(self._description) == str # noqa: E721
|
|
186
|
+
assert self._files is None or isinstance(self._files, typing.Iterable)
|
|
187
|
+
|
|
188
|
+
msg = []
|
|
189
|
+
|
|
190
|
+
if self._description:
|
|
191
|
+
msg.append(self._description)
|
|
192
|
+
|
|
193
|
+
for f, lines in self._files or []:
|
|
194
|
+
assert type(f) == str # noqa: E721
|
|
195
|
+
assert type(lines) in [str, bytes] # noqa: E721
|
|
196
|
+
msg.append(u'{}\n----\n{}\n'.format(f, lines))
|
|
197
|
+
|
|
198
|
+
return six.text_type('\n').join(msg)
|
|
199
|
+
|
|
200
|
+
@property
|
|
201
|
+
def description(self) -> typing.Optional[str]:
|
|
202
|
+
assert self._description is None or type(self._description) == str # noqa: E721
|
|
203
|
+
return self._description
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def files(self) -> typing.Optional[typing.Iterable]:
|
|
207
|
+
assert self._files is None or isinstance(self._files, typing.Iterable)
|
|
208
|
+
return self._files
|
|
209
|
+
|
|
210
|
+
def __repr__(self) -> str:
|
|
211
|
+
args = []
|
|
212
|
+
|
|
213
|
+
if self._description is not None:
|
|
214
|
+
args.append(("message", self._description))
|
|
215
|
+
|
|
216
|
+
if self._files is not None:
|
|
217
|
+
args.append(("files", self._files))
|
|
218
|
+
|
|
219
|
+
result = "{}(".format(type(self).__name__)
|
|
220
|
+
sep = ""
|
|
221
|
+
for a in args:
|
|
222
|
+
result += sep + a[0] + "=" + repr(a[1])
|
|
223
|
+
sep = ", "
|
|
224
|
+
continue
|
|
225
|
+
result += ")"
|
|
226
|
+
return result
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class InitNodeException(TestgresException):
|
|
230
|
+
_message: typing.Optional[str]
|
|
231
|
+
|
|
232
|
+
def __init__(
|
|
233
|
+
self,
|
|
234
|
+
message: typing.Optional[str] = None,
|
|
235
|
+
):
|
|
236
|
+
assert message is None or type(message) == str # noqa: E721
|
|
237
|
+
super().__init__(message)
|
|
238
|
+
self._message = message
|
|
239
|
+
return
|
|
240
|
+
|
|
241
|
+
@property
|
|
242
|
+
def message(self) -> str:
|
|
243
|
+
assert self._message is None or type(self._message) == str # noqa: E721
|
|
244
|
+
if self._message is None:
|
|
245
|
+
return ""
|
|
246
|
+
return self._message
|
|
247
|
+
|
|
248
|
+
def __repr__(self) -> str:
|
|
249
|
+
args = []
|
|
250
|
+
|
|
251
|
+
if self._message is not None:
|
|
252
|
+
args.append(("message", self._message))
|
|
253
|
+
|
|
254
|
+
result = "{}(".format(type(self).__name__)
|
|
255
|
+
sep = ""
|
|
256
|
+
for a in args:
|
|
257
|
+
result += sep + a[0] + "=" + repr(a[1])
|
|
258
|
+
sep = ", "
|
|
259
|
+
continue
|
|
260
|
+
result += ")"
|
|
261
|
+
return result
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
class BackupException(TestgresException):
|
|
265
|
+
_message: typing.Optional[str]
|
|
266
|
+
|
|
267
|
+
def __init__(
|
|
268
|
+
self,
|
|
269
|
+
message: typing.Optional[str] = None,
|
|
270
|
+
):
|
|
271
|
+
assert message is None or type(message) == str # noqa: E721
|
|
272
|
+
super().__init__(message)
|
|
273
|
+
self._message = message
|
|
274
|
+
return
|
|
275
|
+
|
|
276
|
+
@property
|
|
277
|
+
def message(self) -> str:
|
|
278
|
+
assert self._message is None or type(self._message) == str # noqa: E721
|
|
279
|
+
if self._message is None:
|
|
280
|
+
return ""
|
|
281
|
+
return self._message
|
|
282
|
+
|
|
283
|
+
def __repr__(self) -> str:
|
|
284
|
+
args = []
|
|
285
|
+
|
|
286
|
+
if self._message is not None:
|
|
287
|
+
args.append(("message", self._message))
|
|
288
|
+
|
|
289
|
+
result = "{}(".format(type(self).__name__)
|
|
290
|
+
sep = ""
|
|
291
|
+
for a in args:
|
|
292
|
+
result += sep + a[0] + "=" + repr(a[1])
|
|
293
|
+
sep = ", "
|
|
294
|
+
continue
|
|
295
|
+
result += ")"
|
|
296
|
+
return result
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
assert ExecUtilException.__name__ == "ExecUtilException"
|
|
300
|
+
assert InvalidOperationException.__name__ == "InvalidOperationException"
|