crate 1.0.0.dev1__py3-none-any.whl → 1.0.1__py3-none-any.whl

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.
crate/testing/__init__.py CHANGED
@@ -1 +0,0 @@
1
- # package
crate/testing/layer.py CHANGED
@@ -19,38 +19,44 @@
19
19
  # with Crate these terms will supersede the license and you may use the
20
20
  # software solely pursuant to the terms of the relevant commercial agreement.
21
21
 
22
+ # ruff: noqa: S603 # `subprocess` call: check for execution of untrusted input
23
+ # ruff: noqa: S202 # Uses of `tarfile.extractall()`
24
+
25
+ import io
26
+ import json
27
+ import logging
22
28
  import os
23
29
  import re
24
- import sys
25
- import time
26
- import json
27
- import urllib3
28
- import tempfile
29
30
  import shutil
30
31
  import subprocess
32
+ import sys
31
33
  import tarfile
32
- import io
34
+ import tempfile
33
35
  import threading
34
- import logging
36
+ import time
37
+
38
+ import urllib3
35
39
 
36
40
  try:
37
41
  from urllib.request import urlopen
38
42
  except ImportError:
39
- from urllib import urlopen
43
+ from urllib import urlopen # type: ignore[attr-defined,no-redef]
40
44
 
41
45
 
42
46
  log = logging.getLogger(__name__)
43
47
 
44
48
 
45
- CRATE_CONFIG_ERROR = 'crate_config must point to a folder or to a file named "crate.yml"'
49
+ CRATE_CONFIG_ERROR = (
50
+ 'crate_config must point to a folder or to a file named "crate.yml"'
51
+ )
46
52
  HTTP_ADDRESS_RE = re.compile(
47
- r'.*\[(http|.*HttpServer.*)\s*] \[.*\] .*'
48
- 'publish_address {'
49
- r'(?:inet\[[\w\d\.-]*/|\[)?'
50
- r'(?:[\w\d\.-]+/)?'
51
- r'(?P<addr>[\d\.:]+)'
52
- r'(?:\])?'
53
- '}'
53
+ r".*\[(http|.*HttpServer.*)\s*] \[.*\] .*"
54
+ "publish_address {"
55
+ r"(?:inet\[[\w\d\.-]*/|\[)?"
56
+ r"(?:[\w\d\.-]+/)?"
57
+ r"(?P<addr>[\d\.:]+)"
58
+ r"(?:\])?"
59
+ "}"
54
60
  )
55
61
 
56
62
 
@@ -61,18 +67,22 @@ def http_url_from_host_port(host, port):
61
67
  port = int(port)
62
68
  except ValueError:
63
69
  return None
64
- return '{}:{}'.format(prepend_http(host), port)
70
+ return "{}:{}".format(prepend_http(host), port)
65
71
  return None
66
72
 
67
73
 
68
74
  def prepend_http(host):
69
- if not re.match(r'^https?\:\/\/.*', host):
70
- return 'http://{}'.format(host)
75
+ if not re.match(r"^https?\:\/\/.*", host):
76
+ return "http://{}".format(host)
71
77
  return host
72
78
 
73
79
 
74
80
  def _download_and_extract(uri, directory):
75
- sys.stderr.write("\nINFO: Downloading CrateDB archive from {} into {}".format(uri, directory))
81
+ sys.stderr.write(
82
+ "\nINFO: Downloading CrateDB archive from {} into {}".format(
83
+ uri, directory
84
+ )
85
+ )
76
86
  sys.stderr.flush()
77
87
  with io.BytesIO(urlopen(uri).read()) as tmpfile:
78
88
  with tarfile.open(fileobj=tmpfile) as t:
@@ -82,19 +92,18 @@ def _download_and_extract(uri, directory):
82
92
  def wait_for_http_url(log, timeout=30, verbose=False):
83
93
  start = time.monotonic()
84
94
  while True:
85
- line = log.readline().decode('utf-8').strip()
95
+ line = log.readline().decode("utf-8").strip()
86
96
  elapsed = time.monotonic() - start
87
97
  if verbose:
88
- sys.stderr.write('[{:>4.1f}s]{}\n'.format(elapsed, line))
98
+ sys.stderr.write("[{:>4.1f}s]{}\n".format(elapsed, line))
89
99
  m = HTTP_ADDRESS_RE.match(line)
90
100
  if m:
91
- return prepend_http(m.group('addr'))
101
+ return prepend_http(m.group("addr"))
92
102
  elif elapsed > timeout:
93
103
  return None
94
104
 
95
105
 
96
106
  class OutputMonitor:
97
-
98
107
  def __init__(self):
99
108
  self.consumers = []
100
109
 
@@ -105,7 +114,9 @@ class OutputMonitor:
105
114
 
106
115
  def start(self, proc):
107
116
  self._stop_out_thread = threading.Event()
108
- self._out_thread = threading.Thread(target=self.consume, args=(proc.stdout,))
117
+ self._out_thread = threading.Thread(
118
+ target=self.consume, args=(proc.stdout,)
119
+ )
109
120
  self._out_thread.daemon = True
110
121
  self._out_thread.start()
111
122
 
@@ -116,7 +127,6 @@ class OutputMonitor:
116
127
 
117
128
 
118
129
  class LineBuffer:
119
-
120
130
  def __init__(self):
121
131
  self.lines = []
122
132
 
@@ -124,7 +134,7 @@ class LineBuffer:
124
134
  self.lines.append(line.strip())
125
135
 
126
136
 
127
- class CrateLayer(object):
137
+ class CrateLayer:
128
138
  """
129
139
  This layer starts a Crate server.
130
140
  """
@@ -135,14 +145,16 @@ class CrateLayer(object):
135
145
  wait_interval = 0.2
136
146
 
137
147
  @staticmethod
138
- def from_uri(uri,
139
- name,
140
- http_port='4200-4299',
141
- transport_port='4300-4399',
142
- settings=None,
143
- directory=None,
144
- cleanup=True,
145
- verbose=False):
148
+ def from_uri(
149
+ uri,
150
+ name,
151
+ http_port="4200-4299",
152
+ transport_port="4300-4399",
153
+ settings=None,
154
+ directory=None,
155
+ cleanup=True,
156
+ verbose=False,
157
+ ):
146
158
  """Download the Crate tarball from a URI and create a CrateLayer
147
159
 
148
160
  :param uri: The uri that points to the Crate tarball
@@ -158,11 +170,14 @@ class CrateLayer(object):
158
170
  """
159
171
  directory = directory or tempfile.mkdtemp()
160
172
  filename = os.path.basename(uri)
161
- crate_dir = re.sub(r'\.tar(\.gz)?$', '', filename)
173
+ crate_dir = re.sub(r"\.tar(\.gz)?$", "", filename)
162
174
  crate_home = os.path.join(directory, crate_dir)
163
175
 
164
176
  if os.path.exists(crate_home):
165
- sys.stderr.write("\nWARNING: Not extracting Crate tarball because folder already exists")
177
+ sys.stderr.write(
178
+ "\nWARNING: Not extracting CrateDB tarball"
179
+ " because folder already exists"
180
+ )
166
181
  sys.stderr.flush()
167
182
  else:
168
183
  _download_and_extract(uri, directory)
@@ -173,29 +188,33 @@ class CrateLayer(object):
173
188
  port=http_port,
174
189
  transport_port=transport_port,
175
190
  settings=settings,
176
- verbose=verbose)
191
+ verbose=verbose,
192
+ )
177
193
  if cleanup:
178
194
  tearDown = layer.tearDown
179
195
 
180
196
  def new_teardown(*args, **kws):
181
197
  shutil.rmtree(directory)
182
198
  tearDown(*args, **kws)
183
- layer.tearDown = new_teardown
199
+
200
+ layer.tearDown = new_teardown # type: ignore[method-assign]
184
201
  return layer
185
202
 
186
- def __init__(self,
187
- name,
188
- crate_home,
189
- crate_config=None,
190
- port=None,
191
- keepRunning=False,
192
- transport_port=None,
193
- crate_exec=None,
194
- cluster_name=None,
195
- host="127.0.0.1",
196
- settings=None,
197
- verbose=False,
198
- env=None):
203
+ def __init__(
204
+ self,
205
+ name,
206
+ crate_home,
207
+ crate_config=None,
208
+ port=None,
209
+ keepRunning=False,
210
+ transport_port=None,
211
+ crate_exec=None,
212
+ cluster_name=None,
213
+ host="127.0.0.1",
214
+ settings=None,
215
+ verbose=False,
216
+ env=None,
217
+ ):
199
218
  """
200
219
  :param name: layer name, is also used as the cluser name
201
220
  :param crate_home: path to home directory of the crate installation
@@ -216,52 +235,69 @@ class CrateLayer(object):
216
235
  self.__name__ = name
217
236
  if settings and isinstance(settings, dict):
218
237
  # extra settings may override host/port specification!
219
- self.http_url = http_url_from_host_port(settings.get('network.host', host),
220
- settings.get('http.port', port))
238
+ self.http_url = http_url_from_host_port(
239
+ settings.get("network.host", host),
240
+ settings.get("http.port", port),
241
+ )
221
242
  else:
222
243
  self.http_url = http_url_from_host_port(host, port)
223
244
 
224
245
  self.process = None
225
246
  self.verbose = verbose
226
247
  self.env = env or {}
227
- self.env.setdefault('CRATE_USE_IPV4', 'true')
228
- self.env.setdefault('JAVA_HOME', os.environ.get('JAVA_HOME', ''))
248
+ self.env.setdefault("CRATE_USE_IPV4", "true")
249
+ self.env.setdefault("JAVA_HOME", os.environ.get("JAVA_HOME", ""))
229
250
  self._stdout_consumers = []
230
251
  self.conn_pool = urllib3.PoolManager(num_pools=1)
231
252
 
232
253
  crate_home = os.path.abspath(crate_home)
233
254
  if crate_exec is None:
234
- start_script = 'crate.bat' if sys.platform == 'win32' else 'crate'
235
- crate_exec = os.path.join(crate_home, 'bin', start_script)
255
+ start_script = "crate.bat" if sys.platform == "win32" else "crate"
256
+ crate_exec = os.path.join(crate_home, "bin", start_script)
236
257
  if crate_config is None:
237
- crate_config = os.path.join(crate_home, 'config', 'crate.yml')
238
- elif (os.path.isfile(crate_config) and
239
- os.path.basename(crate_config) != 'crate.yml'):
258
+ crate_config = os.path.join(crate_home, "config", "crate.yml")
259
+ elif (
260
+ os.path.isfile(crate_config)
261
+ and os.path.basename(crate_config) != "crate.yml"
262
+ ):
240
263
  raise ValueError(CRATE_CONFIG_ERROR)
241
264
  if cluster_name is None:
242
- cluster_name = "Testing{0}".format(port or 'Dynamic')
243
- settings = self.create_settings(crate_config,
244
- cluster_name,
245
- name,
246
- host,
247
- port or '4200-4299',
248
- transport_port or '4300-4399',
249
- settings)
265
+ cluster_name = "Testing{0}".format(port or "Dynamic")
266
+ settings = self.create_settings(
267
+ crate_config,
268
+ cluster_name,
269
+ name,
270
+ host,
271
+ port or "4200-4299",
272
+ transport_port or "4300-4399",
273
+ settings,
274
+ )
250
275
  # ES 5 cannot parse 'True'/'False' as booleans so convert to lowercase
251
- start_cmd = (crate_exec, ) + tuple(["-C%s=%s" % ((key, str(value).lower()) if isinstance(value, bool) else (key, value))
252
- for key, value in settings.items()])
253
-
254
- self._wd = wd = os.path.join(CrateLayer.tmpdir, 'crate_layer', name)
255
- self.start_cmd = start_cmd + ('-Cpath.data=%s' % wd,)
256
-
257
- def create_settings(self,
258
- crate_config,
259
- cluster_name,
260
- node_name,
261
- host,
262
- http_port,
263
- transport_port,
264
- further_settings=None):
276
+ start_cmd = (crate_exec,) + tuple(
277
+ [
278
+ "-C%s=%s"
279
+ % (
280
+ (key, str(value).lower())
281
+ if isinstance(value, bool)
282
+ else (key, value)
283
+ )
284
+ for key, value in settings.items()
285
+ ]
286
+ )
287
+
288
+ self._wd = wd = os.path.join(CrateLayer.tmpdir, "crate_layer", name)
289
+ self.start_cmd = start_cmd + ("-Cpath.data=%s" % wd,)
290
+
291
+ def create_settings(
292
+ self,
293
+ crate_config,
294
+ cluster_name,
295
+ node_name,
296
+ host,
297
+ http_port,
298
+ transport_port,
299
+ further_settings=None,
300
+ ):
265
301
  settings = {
266
302
  "discovery.type": "zen",
267
303
  "discovery.initial_state_timeout": 0,
@@ -294,20 +330,23 @@ class CrateLayer(object):
294
330
 
295
331
  def start(self):
296
332
  self._clean()
297
- self.process = subprocess.Popen(self.start_cmd,
298
- env=self.env,
299
- stdout=subprocess.PIPE)
333
+ self.process = subprocess.Popen(
334
+ self.start_cmd, env=self.env, stdout=subprocess.PIPE
335
+ )
300
336
  returncode = self.process.poll()
301
337
  if returncode is not None:
302
338
  raise SystemError(
303
- 'Failed to start server rc={0} cmd={1}'.format(returncode,
304
- self.start_cmd)
339
+ "Failed to start server rc={0} cmd={1}".format(
340
+ returncode, self.start_cmd
341
+ )
305
342
  )
306
343
 
307
344
  if not self.http_url:
308
345
  # try to read http_url from startup logs
309
346
  # this is necessary if no static port is assigned
310
- self.http_url = wait_for_http_url(self.process.stdout, verbose=self.verbose)
347
+ self.http_url = wait_for_http_url(
348
+ self.process.stdout, verbose=self.verbose
349
+ )
311
350
 
312
351
  self.monitor = OutputMonitor()
313
352
  self.monitor.start(self.process)
@@ -315,10 +354,10 @@ class CrateLayer(object):
315
354
  if not self.http_url:
316
355
  self.stop()
317
356
  else:
318
- sys.stderr.write('HTTP: {}\n'.format(self.http_url))
357
+ sys.stderr.write("HTTP: {}\n".format(self.http_url))
319
358
  self._wait_for_start()
320
359
  self._wait_for_master()
321
- sys.stderr.write('\nCrate instance ready.\n')
360
+ sys.stderr.write("\nCrate instance ready.\n")
322
361
 
323
362
  def stop(self):
324
363
  self.conn_pool.clear()
@@ -352,10 +391,9 @@ class CrateLayer(object):
352
391
  for line in line_buf.lines:
353
392
  log.error(line)
354
393
  self.stop()
355
- raise SystemError('Failed to start Crate instance in time.')
356
- else:
357
- sys.stderr.write('.')
358
- time.sleep(self.wait_interval)
394
+ raise SystemError("Failed to start Crate instance in time.")
395
+ sys.stderr.write(".")
396
+ time.sleep(self.wait_interval)
359
397
 
360
398
  self.monitor.consumers.remove(line_buf)
361
399
 
@@ -367,7 +405,7 @@ class CrateLayer(object):
367
405
  # after the layer starts don't result in 503
368
406
  def validator():
369
407
  try:
370
- resp = self.conn_pool.request('HEAD', self.http_url)
408
+ resp = self.conn_pool.request("HEAD", self.http_url)
371
409
  return resp.status == 200
372
410
  except Exception:
373
411
  return False
@@ -379,12 +417,12 @@ class CrateLayer(object):
379
417
 
380
418
  def validator():
381
419
  resp = self.conn_pool.urlopen(
382
- 'POST',
383
- '{server}/_sql'.format(server=self.http_url),
384
- headers={'Content-Type': 'application/json'},
385
- body='{"stmt": "select master_node from sys.cluster"}'
420
+ "POST",
421
+ "{server}/_sql".format(server=self.http_url),
422
+ headers={"Content-Type": "application/json"},
423
+ body='{"stmt": "select master_node from sys.cluster"}',
386
424
  )
387
- data = json.loads(resp.data.decode('utf-8'))
388
- return resp.status == 200 and data['rows'][0][0]
425
+ data = json.loads(resp.data.decode("utf-8"))
426
+ return resp.status == 200 and data["rows"][0][0]
389
427
 
390
428
  self._wait_for(validator)
crate/testing/util.py CHANGED
@@ -1,4 +1,75 @@
1
- class ExtraAssertions:
1
+ # -*- coding: utf-8; -*-
2
+ #
3
+ # Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
4
+ # license agreements. See the NOTICE file distributed with this work for
5
+ # additional information regarding copyright ownership. Crate licenses
6
+ # this file to you under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License. You may
8
+ # obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
+ # License for the specific language governing permissions and limitations
16
+ # under the License.
17
+ #
18
+ # However, if you have executed another commercial license agreement
19
+ # with Crate these terms will supersede the license and you may use the
20
+ # software solely pursuant to the terms of the relevant commercial agreement.
21
+ import unittest
22
+
23
+
24
+ class ClientMocked:
25
+ active_servers = ["http://localhost:4200"]
26
+
27
+ def __init__(self):
28
+ self.response = {}
29
+ self._server_infos = ("http://localhost:4200", "my server", "2.0.0")
30
+
31
+ def sql(self, stmt=None, parameters=None, bulk_parameters=None):
32
+ return self.response
33
+
34
+ def server_infos(self, server):
35
+ return self._server_infos
36
+
37
+ def set_next_response(self, response):
38
+ self.response = response
39
+
40
+ def set_next_server_infos(self, server, server_name, version):
41
+ self._server_infos = (server, server_name, version)
42
+
43
+ def close(self):
44
+ pass
45
+
46
+
47
+ class ParametrizedTestCase(unittest.TestCase):
48
+ """
49
+ TestCase classes that want to be parametrized should
50
+ inherit from this class.
51
+
52
+ https://eli.thegreenplace.net/2011/08/02/python-unit-testing-parametrized-test-cases
53
+ """
54
+
55
+ def __init__(self, methodName="runTest", param=None):
56
+ super(ParametrizedTestCase, self).__init__(methodName)
57
+ self.param = param
58
+
59
+ @staticmethod
60
+ def parametrize(testcase_klass, param=None):
61
+ """Create a suite containing all tests taken from the given
62
+ subclass, passing them the parameter 'param'.
63
+ """
64
+ testloader = unittest.TestLoader()
65
+ testnames = testloader.getTestCaseNames(testcase_klass)
66
+ suite = unittest.TestSuite()
67
+ for name in testnames:
68
+ suite.addTest(testcase_klass(name, param=param))
69
+ return suite
70
+
71
+
72
+ class ExtraAssertions(unittest.TestCase):
2
73
  """
3
74
  Additional assert methods for unittest.
4
75
 
@@ -12,9 +83,13 @@ class ExtraAssertions:
12
83
  r = issubclass(cls, superclass)
13
84
  except TypeError:
14
85
  if not isinstance(cls, type):
15
- self.fail(self._formatMessage(msg,
16
- '%r is not a class' % (cls,)))
86
+ self.fail(
87
+ self._formatMessage(msg, "%r is not a class" % (cls,))
88
+ )
17
89
  raise
18
90
  if not r:
19
- self.fail(self._formatMessage(msg,
20
- '%r is not a subclass of %r' % (cls, superclass)))
91
+ self.fail(
92
+ self._formatMessage(
93
+ msg, "%r is not a subclass of %r" % (cls, superclass)
94
+ )
95
+ )
@@ -176,73 +176,3 @@
176
176
  of your accepting any such warranty or additional liability.
177
177
 
178
178
  END OF TERMS AND CONDITIONS
179
-
180
- APPENDIX: How to apply the Apache License to your work.
181
-
182
- To apply the Apache License to your work, attach the following
183
- boilerplate notice, with the fields enclosed by brackets "[]"
184
- replaced with your own identifying information. (Don't include
185
- the brackets!) The text should be enclosed in the appropriate
186
- comment syntax for the file format. We also recommend that a
187
- file or class name and description of purpose be included on the
188
- same "printed page" as the copyright notice for easier
189
- identification within third-party archives.
190
-
191
- Copyright [yyyy] [name of copyright owner]
192
-
193
- Licensed under the Apache License, Version 2.0 (the "License");
194
- you may not use this file except in compliance with the License.
195
- You may obtain a copy of the License at
196
-
197
- http://www.apache.org/licenses/LICENSE-2.0
198
-
199
- Unless required by applicable law or agreed to in writing, software
200
- distributed under the License is distributed on an "AS IS" BASIS,
201
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
202
- See the License for the specific language governing permissions and
203
- limitations under the License.
204
-
205
-
206
- ===============================================================================
207
-
208
- For the `docs` directory:
209
-
210
- The source files for the documentation are licensed under the Apache License
211
- Version 2.0. These source files are used by the project maintainers to build
212
- online documentation for end-users:
213
-
214
- <https://crate.io/docs/clients/python/en/latest/>
215
-
216
- If you want to make contributions to the documentation, it may be necessary for
217
- you to build the documentation yourself by following the instructions in the
218
- `DEVELOP.rst` file. If you do this, a number of third-party software components
219
- are necessary.
220
-
221
- We do not ship the source code for these optional third-party software
222
- components or their dependencies, so we cannot make any guarantees about the
223
- licensing status of these components.
224
-
225
- However, for convenience, the documentation build system explicitly references
226
- the following software components (grouped by license):
227
-
228
- PSF License:
229
-
230
- - Python 3 <https://docs.python.org/3/license.html>
231
-
232
- MIT License:
233
-
234
- - pip <https://pypi.org/project/pip/>
235
- - setuptools <https://pypi.org/project/setuptools/>
236
- - sphinx-autobuild <https://pypi.org/project/sphinx-autobuild/>
237
-
238
- BSD License:
239
-
240
- - alabaster <https://pypi.org/project/alabaster/>
241
- - sphinx <https://pypi.org/project/Sphinx/>
242
-
243
- Apache License 2.0:
244
-
245
- - crate-docs-theme <https://pypi.org/project/crate-docs-theme/>
246
-
247
- Please note that each of these components may specify its own dependencies and
248
- those dependencies may be licensed differently.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crate
3
- Version: 1.0.0.dev1
3
+ Version: 1.0.1
4
4
  Summary: CrateDB Python Client
5
5
  Home-page: https://github.com/crate/crate-python
6
6
  Author: Crate.io
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.9
21
21
  Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
24
25
  Classifier: Programming Language :: Python :: Implementation :: CPython
25
26
  Classifier: Programming Language :: Python :: Implementation :: PyPy
26
27
  Classifier: Topic :: Database
@@ -28,25 +29,24 @@ Requires-Python: >=3.6
28
29
  Description-Content-Type: text/x-rst
29
30
  License-File: LICENSE
30
31
  License-File: NOTICE
31
- Requires-Dist: urllib3<2.3
32
- Requires-Dist: verlib2==0.2.0
32
+ Requires-Dist: urllib3
33
+ Requires-Dist: verlib2
33
34
  Provides-Extra: doc
34
- Requires-Dist: sphinx<8,>=3.5; extra == "doc"
35
35
  Requires-Dist: crate-docs-theme>=0.26.5; extra == "doc"
36
+ Requires-Dist: sphinx<9,>=3.5; extra == "doc"
36
37
  Provides-Extra: test
37
- Requires-Dist: tox<5,>=3; extra == "test"
38
- Requires-Dist: zope.testing<6,>=4; extra == "test"
39
- Requires-Dist: zope.testrunner<7,>=5; extra == "test"
40
- Requires-Dist: zc.customdoctests<2,>=1.0.1; extra == "test"
38
+ Requires-Dist: backports.zoneinfo<1; python_version < "3.9" and extra == "test"
41
39
  Requires-Dist: certifi; extra == "test"
42
40
  Requires-Dist: createcoverage<2,>=1; extra == "test"
43
- Requires-Dist: dask[dataframe]; extra == "test"
41
+ Requires-Dist: mypy<1.14; extra == "test"
42
+ Requires-Dist: poethepoet<0.31; extra == "test"
43
+ Requires-Dist: ruff<0.8; extra == "test"
44
44
  Requires-Dist: stopit<2,>=1.1.2; extra == "test"
45
- Requires-Dist: flake8<8,>=4; extra == "test"
46
- Requires-Dist: pandas<2.3; extra == "test"
47
- Requires-Dist: pueblo>=0.0.7; extra == "test"
45
+ Requires-Dist: tox<5,>=3; extra == "test"
48
46
  Requires-Dist: pytz; extra == "test"
49
- Requires-Dist: backports.zoneinfo<1; python_version < "3.9" and extra == "test"
47
+ Requires-Dist: zc.customdoctests<2,>=1.0.1; extra == "test"
48
+ Requires-Dist: zope.testing<6,>=4; extra == "test"
49
+ Requires-Dist: zope.testrunner<7,>=5; extra == "test"
50
50
 
51
51
  =====================
52
52
  CrateDB Python Client
@@ -56,7 +56,7 @@ CrateDB Python Client
56
56
  :target: https://github.com/crate/crate-python/actions?workflow=Tests
57
57
  :alt: Build status
58
58
 
59
- .. image:: https://codecov.io/gh/crate/crate-python/branch/master/graph/badge.svg
59
+ .. image:: https://codecov.io/gh/crate/crate-python/branch/main/graph/badge.svg
60
60
  :target: https://app.codecov.io/gh/crate/crate-python
61
61
  :alt: Coverage
62
62
 
@@ -152,5 +152,3 @@ GitHub`_. We appreciate contributions of any kind.
152
152
  .. _sqlalchemy-cratedb documentation: https://cratedb.com/docs/sqlalchemy-cratedb/
153
153
  .. _StackOverflow: https://stackoverflow.com/tags/cratedb
154
154
  .. _support channels: https://cratedb.com/support/
155
-
156
-
@@ -1,5 +1,5 @@
1
1
  CrateDB Python Adapter
2
- Copyright 2013-2022 Crate.IO GmbH ("Crate")
2
+ Copyright 2013-2024 Crate.IO GmbH ("Crate")
3
3
 
4
4
 
5
5
  Licensed to Crate.IO GmbH (referred to in this notice as "Crate") under one or