Skip to content

Commit 90369c1

Browse files
committed
Warnings overhaul
* Fix falsely emitted `DeprecationWarning` regarding `update_routing_table_timeout`. * Treat warnings as errors during testing * Changed tests to expect and catch warning or to avoid them.
1 parent 7f6506d commit 90369c1

21 files changed

+224
-63
lines changed

neo4j/io/__init__.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -277,18 +277,19 @@ def get_handshake(cls):
277277
return b"".join(version.to_bytes() for version in offered_versions).ljust(16, b"\x00")
278278

279279
@classmethod
280-
def ping(cls, address, *, timeout=None, **config):
280+
def ping(cls, address, *, timeout=None, pool_config=None):
281281
""" Attempt to establish a Bolt connection, returning the
282282
agreed Bolt protocol version if successful.
283283
"""
284-
config = PoolConfig.consume(config)
284+
if pool_config is None:
285+
pool_config = PoolConfig()
285286
try:
286287
s, protocol_version, handshake, data = BoltSocket.connect(
287288
address,
288289
timeout=timeout,
289-
custom_resolver=config.resolver,
290-
ssl_context=config.get_ssl_context(),
291-
keep_alive=config.keep_alive,
290+
custom_resolver=pool_config.resolver,
291+
ssl_context=pool_config.get_ssl_context(),
292+
keep_alive=pool_config.keep_alive,
292293
)
293294
except (ServiceUnavailable, SessionExpired, BoltHandshakeError):
294295
return None
@@ -297,7 +298,8 @@ def ping(cls, address, *, timeout=None, **config):
297298
return protocol_version
298299

299300
@classmethod
300-
def open(cls, address, *, auth=None, timeout=None, routing_context=None, **pool_config):
301+
def open(cls, address, *, auth=None, timeout=None, routing_context=None,
302+
pool_config=None):
301303
""" Open a new Bolt connection to a given server address.
302304
303305
:param address:
@@ -316,7 +318,8 @@ def time_remaining():
316318
return t if t > 0 else 0
317319

318320
t0 = perf_counter()
319-
pool_config = PoolConfig.consume(pool_config)
321+
if pool_config is None:
322+
pool_config = PoolConfig()
320323

321324
socket_connection_timeout = pool_config.connection_timeout
322325
if socket_connection_timeout is None:
@@ -906,7 +909,7 @@ def open(cls, address, *, auth, pool_config, workspace_config):
906909
def opener(addr, timeout):
907910
return Bolt.open(
908911
addr, auth=auth, timeout=timeout, routing_context=None,
909-
**pool_config
912+
pool_config=pool_config
910913
)
911914

912915
pool = cls(opener, pool_config, workspace_config, address)
@@ -951,7 +954,8 @@ def open(cls, *addresses, auth, pool_config, workspace_config, routing_context=N
951954

952955
def opener(addr, timeout):
953956
return Bolt.open(addr, auth=auth, timeout=timeout,
954-
routing_context=routing_context, **pool_config)
957+
routing_context=routing_context,
958+
pool_config=pool_config)
955959

956960
pool = cls(opener, pool_config, workspace_config, address)
957961
return pool

neo4j/io/_socket.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def _handshake(cls, s, resolved_address):
259259
def close_socket(cls, socket_):
260260
try:
261261
if isinstance(socket_, BoltSocket):
262-
socket.close()
262+
socket_.close()
263263
else:
264264
socket_.shutdown(SHUT_RDWR)
265265
socket_.close()

neo4j/time/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ def __mul__(self, other):
482482
:rtype: Duration
483483
"""
484484
if isinstance(other, float):
485-
deprecation_warn("Multiplication with float will be deprecated in "
485+
deprecation_warn("Multiplication with float will be removed in "
486486
"5.0.")
487487
if isinstance(other, (int, float)):
488488
return Duration(
@@ -1627,7 +1627,7 @@ def from_clock_time(cls, clock_time, epoch):
16271627
ts = clock_time.seconds % 86400
16281628
nanoseconds = int(NANO_SECONDS * ts + clock_time.nanoseconds)
16291629
ticks = (epoch.time().ticks_ns + nanoseconds) % (86400 * NANO_SECONDS)
1630-
return Time.from_ticks_ns(ticks)
1630+
return cls.from_ticks_ns(ticks)
16311631

16321632
@classmethod
16331633
def __normalize_hour(cls, hour):
@@ -1657,8 +1657,8 @@ def __normalize_nanosecond(cls, hour, minute, second, nanosecond):
16571657
# TODO 5.0: remove -----------------------------------------------------
16581658
seconds, extra_ns = divmod(second, 1)
16591659
if extra_ns:
1660-
deprecation_warn("Float support second will be removed in 5.0. "
1661-
"Use `nanosecond` instead.")
1660+
deprecation_warn("Float support for `second` will be removed in "
1661+
"5.0. Use `nanosecond` instead.")
16621662
# ----------------------------------------------------------------------
16631663
hour, minute, second = cls.__normalize_second(hour, minute, second)
16641664
nanosecond = int(nanosecond
@@ -1753,7 +1753,7 @@ def nanosecond(self):
17531753
return self.__nanosecond
17541754

17551755
@property
1756-
@deprecated("hour_minute_second will be removed in 5.0. "
1756+
@deprecated("`hour_minute_second` will be removed in 5.0. "
17571757
"Use `hour_minute_second_nanosecond` instead.")
17581758
def hour_minute_second(self):
17591759
"""The time as a tuple of (hour, minute, second).

testkit/backend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33

44
if __name__ == "__main__":
55
subprocess.check_call(
6-
["python", "-m", "testkitbackend"],
6+
["python", "-W", "error", "-m", "testkitbackend"],
77
stdout=sys.stdout, stderr=sys.stderr
88
)

testkitbackend/__main__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
import warnings
2+
13
from .server import Server
24

5+
36
if __name__ == "__main__":
7+
warnings.simplefilter("error")
48
server = Server(("0.0.0.0", 9876))
59
while True:
610
server.handle_request()

testkitbackend/requests.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# limitations under the License.
1717
import json
1818
from os import path
19+
import warnings
1920

2021
import neo4j
2122
import testkitbackend.fromtestkit as fromtestkit
@@ -108,7 +109,9 @@ def NewDriver(backend, data):
108109
def VerifyConnectivity(backend, data):
109110
driver_id = data["driverId"]
110111
driver = backend.drivers[driver_id]
111-
driver.verify_connectivity()
112+
with warnings.catch_warnings():
113+
warnings.simplefilter("ignore", category=neo4j.ExperimentalWarning)
114+
driver.verify_connectivity()
112115
backend.send_response("Driver", {"id": driver_id})
113116

114117

tests/integration/conftest.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@
4343
NEO4J_RELEASES = getenv("NEO4J_RELEASES", "snapshot-enterprise 3.5-enterprise").split()
4444
NEO4J_HOST = "localhost"
4545
NEO4J_PORTS = {
46-
"bolt": 17601,
46+
"bolt": 7687,
4747
"http": 17401,
4848
"https": 17301,
4949
}
50-
NEO4J_CORES = 3
51-
NEO4J_REPLICAS = 2
50+
NEO4J_CORES = 1
51+
NEO4J_REPLICAS = 0
5252
NEO4J_USER = "neo4j"
53-
NEO4J_PASSWORD = "password"
53+
NEO4J_PASSWORD = "pass"
5454
NEO4J_AUTH = (NEO4J_USER, NEO4J_PASSWORD)
5555
NEO4J_LOCK = RLock()
5656
NEO4J_SERVICE = None

tests/integration/examples/test_database_selection_example.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ class DatabaseSelectionExample:
4242
def __init__(self, uri, user, password):
4343
self.driver = GraphDatabase.driver(uri, auth=(user, password))
4444
with self.driver.session(database="system") as session:
45-
session.run("DROP DATABASE example IF EXISTS").consume()
46-
session.run("CREATE DATABASE example").consume()
45+
session.run("DROP DATABASE example IF EXISTS WAIT").consume()
46+
session.run("CREATE DATABASE example WAIT").consume()
4747

4848
def close(self):
4949
with self.driver.session(database="system") as session:
50-
session.run("DROP DATABASE example").consume()
50+
session.run("DROP DATABASE example WAIT").consume()
5151
self.driver.close()
5252

5353
def run_example_code(self):

tests/integration/test_temporal_types.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def test_whole_second_time_input(cypher_eval):
8989
def test_nanosecond_resolution_time_input(cypher_eval):
9090
result = cypher_eval("CYPHER runtime=interpreted WITH $x AS x "
9191
"RETURN [x.hour, x.minute, x.second, x.nanosecond]",
92-
x=Time(12, 34, 56.789012345))
92+
x=Time(12, 34, 56, 789012345))
9393
hour, minute, second, nanosecond = result
9494
assert hour == 12
9595
assert minute == 34
@@ -101,7 +101,7 @@ def test_time_with_numeric_time_offset_input(cypher_eval):
101101
result = cypher_eval("CYPHER runtime=interpreted WITH $x AS x "
102102
"RETURN [x.hour, x.minute, x.second, "
103103
" x.nanosecond, x.offset]",
104-
x=Time(12, 34, 56.789012345, tzinfo=FixedOffset(90)))
104+
x=Time(12, 34, 56, 789012345, tzinfo=FixedOffset(90)))
105105
hour, minute, second, nanosecond, offset = result
106106
assert hour == 12
107107
assert minute == 34
@@ -150,7 +150,7 @@ def test_nanosecond_resolution_datetime_input(cypher_eval):
150150
result = cypher_eval("CYPHER runtime=interpreted WITH $x AS x "
151151
"RETURN [x.year, x.month, x.day, "
152152
" x.hour, x.minute, x.second, x.nanosecond]",
153-
x=DateTime(1976, 6, 13, 12, 34, 56.789012345))
153+
x=DateTime(1976, 6, 13, 12, 34, 56, 789012345))
154154
year, month, day, hour, minute, second, nanosecond = result
155155
assert year == 1976
156156
assert month == 6
@@ -166,7 +166,7 @@ def test_datetime_with_numeric_time_offset_input(cypher_eval):
166166
"RETURN [x.year, x.month, x.day, "
167167
" x.hour, x.minute, x.second, "
168168
" x.nanosecond, x.offset]",
169-
x=DateTime(1976, 6, 13, 12, 34, 56.789012345,
169+
x=DateTime(1976, 6, 13, 12, 34, 56, 789012345,
170170
tzinfo=FixedOffset(90)))
171171
year, month, day, hour, minute, second, nanosecond, offset = result
172172
assert year == 1976
@@ -180,7 +180,7 @@ def test_datetime_with_numeric_time_offset_input(cypher_eval):
180180

181181

182182
def test_datetime_with_named_time_zone_input(cypher_eval):
183-
dt = DateTime(1976, 6, 13, 12, 34, 56.789012345)
183+
dt = DateTime(1976, 6, 13, 12, 34, 56, 789012345)
184184
input_value = timezone("US/Pacific").localize(dt)
185185
result = cypher_eval("CYPHER runtime=interpreted WITH $x AS x "
186186
"RETURN [x.year, x.month, x.day, "
@@ -199,7 +199,7 @@ def test_datetime_with_named_time_zone_input(cypher_eval):
199199

200200

201201
def test_datetime_array_input(cypher_eval):
202-
data = [DateTime(2018, 4, 6, 13, 4, 42.516120), DateTime(1976, 6, 13)]
202+
data = [DateTime(2018, 4, 6, 13, 4, 42, 516120), DateTime(1976, 6, 13)]
203203
value = cypher_eval("CREATE (a {x:$x}) RETURN a.x", x=data)
204204
assert value == data
205205

@@ -209,7 +209,7 @@ def test_duration_input(cypher_eval):
209209
"RETURN [x.months, x.days, x.seconds, "
210210
" x.microsecondsOfSecond]",
211211
x=Duration(years=1, months=2, days=3, hours=4,
212-
minutes=5, seconds=6.789012))
212+
minutes=5, seconds=6, microseconds=789012))
213213
months, days, seconds, microseconds = result
214214
assert months == 14
215215
assert days == 3
@@ -258,13 +258,13 @@ def test_whole_second_time_output(cypher_eval):
258258
def test_nanosecond_resolution_time_output(cypher_eval):
259259
value = cypher_eval("RETURN time('12:34:56.789012345')")
260260
assert isinstance(value, Time)
261-
assert value == Time(12, 34, 56.789012345, tzinfo=FixedOffset(0))
261+
assert value == Time(12, 34, 56, 789012345, tzinfo=FixedOffset(0))
262262

263263

264264
def test_time_with_numeric_time_offset_output(cypher_eval):
265265
value = cypher_eval("RETURN time('12:34:56.789012345+0130')")
266266
assert isinstance(value, Time)
267-
assert value == Time(12, 34, 56.789012345, tzinfo=FixedOffset(90))
267+
assert value == Time(12, 34, 56, 789012345, tzinfo=FixedOffset(90))
268268

269269

270270
def test_whole_second_localtime_output(cypher_eval):
@@ -276,7 +276,7 @@ def test_whole_second_localtime_output(cypher_eval):
276276
def test_nanosecond_resolution_localtime_output(cypher_eval):
277277
value = cypher_eval("RETURN localtime('12:34:56.789012345')")
278278
assert isinstance(value, Time)
279-
assert value == Time(12, 34, 56.789012345)
279+
assert value == Time(12, 34, 56, 789012345)
280280

281281

282282
def test_whole_second_datetime_output(cypher_eval):
@@ -288,22 +288,22 @@ def test_whole_second_datetime_output(cypher_eval):
288288
def test_nanosecond_resolution_datetime_output(cypher_eval):
289289
value = cypher_eval("RETURN datetime('1976-06-13T12:34:56.789012345')")
290290
assert isinstance(value, DateTime)
291-
assert value == DateTime(1976, 6, 13, 12, 34, 56.789012345, tzinfo=utc)
291+
assert value == DateTime(1976, 6, 13, 12, 34, 56, 789012345, tzinfo=utc)
292292

293293

294294
def test_datetime_with_numeric_time_offset_output(cypher_eval):
295295
value = cypher_eval("RETURN "
296296
"datetime('1976-06-13T12:34:56.789012345+01:30')")
297297
assert isinstance(value, DateTime)
298-
assert value == DateTime(1976, 6, 13, 12, 34, 56.789012345,
298+
assert value == DateTime(1976, 6, 13, 12, 34, 56, 789012345,
299299
tzinfo=FixedOffset(90))
300300

301301

302302
def test_datetime_with_named_time_zone_output(cypher_eval):
303303
value = cypher_eval("RETURN datetime('1976-06-13T12:34:56.789012345"
304304
"[Europe/London]')")
305305
assert isinstance(value, DateTime)
306-
dt = DateTime(1976, 6, 13, 12, 34, 56.789012345)
306+
dt = DateTime(1976, 6, 13, 12, 34, 56, 789012345)
307307
assert value == timezone("Europe/London").localize(dt)
308308

309309

@@ -317,21 +317,21 @@ def test_nanosecond_resolution_localdatetime_output(cypher_eval):
317317
value = cypher_eval("RETURN "
318318
"localdatetime('1976-06-13T12:34:56.789012345')")
319319
assert isinstance(value, DateTime)
320-
assert value == DateTime(1976, 6, 13, 12, 34, 56.789012345)
320+
assert value == DateTime(1976, 6, 13, 12, 34, 56, 789012345)
321321

322322

323323
def test_duration_output(cypher_eval):
324324
value = cypher_eval("RETURN duration('P1Y2M3DT4H5M6.789S')")
325325
assert isinstance(value, Duration)
326326
assert value == Duration(years=1, months=2, days=3, hours=4,
327-
minutes=5, seconds=6.789)
327+
minutes=5, seconds=6, milliseconds=789)
328328

329329

330330
def test_nanosecond_resolution_duration_output(cypher_eval):
331331
value = cypher_eval("RETURN duration('P1Y2M3DT4H5M6.789123456S')")
332332
assert isinstance(value, Duration)
333333
assert value == Duration(years=1, months=2, days=3, hours=4,
334-
minutes=5, seconds=6.789123456)
334+
minutes=5, seconds=6, nanoseconds=789123456)
335335

336336

337337
def test_datetime_parameter_case1(session):

tests/stub/test_directdriver.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import pytest
2323

24+
import neo4j
2425
from neo4j.exceptions import (
2526
ServiceUnavailable,
2627
ConfigurationError,
@@ -80,7 +81,9 @@ def test_direct_driver_with_wrong_port(driver_info):
8081
uri = "bolt://127.0.0.1:9002"
8182
with pytest.raises(ServiceUnavailable):
8283
driver = GraphDatabase.driver(uri, auth=driver_info["auth_token"], **driver_config)
83-
driver.verify_connectivity()
84+
with pytest.warns(neo4j.ExperimentalWarning,
85+
match="The configuration may change in the future."):
86+
driver.verify_connectivity()
8487

8588

8689
@pytest.mark.parametrize(
@@ -96,7 +99,13 @@ def test_direct_verify_connectivity(driver_info, test_script, test_expected):
9699
uri = "bolt://localhost:9001"
97100
with GraphDatabase.driver(uri, auth=driver_info["auth_token"], **driver_config) as driver:
98101
assert isinstance(driver, BoltDriver)
99-
assert driver.verify_connectivity(default_access_mode=READ_ACCESS) == test_expected
102+
with pytest.warns(
103+
neo4j.ExperimentalWarning,
104+
match="The configuration may change in the future."
105+
):
106+
assert driver.verify_connectivity(
107+
default_access_mode=READ_ACCESS
108+
) == test_expected
100109

101110

102111
@pytest.mark.parametrize(
@@ -112,4 +121,8 @@ def test_direct_verify_connectivity_disconnect_on_run(driver_info, test_script):
112121
uri = "bolt://127.0.0.1:9001"
113122
with GraphDatabase.driver(uri, auth=driver_info["auth_token"], **driver_config) as driver:
114123
with pytest.raises(ServiceUnavailable):
115-
driver.verify_connectivity(default_access_mode=READ_ACCESS)
124+
with pytest.warns(
125+
neo4j.ExperimentalWarning,
126+
match="The configuration may change in the future."
127+
):
128+
driver.verify_connectivity(default_access_mode=READ_ACCESS)

tests/stub/test_routingdriver.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import pytest
2323

2424
from neo4j import (
25+
ExperimentalWarning,
2526
GraphDatabase,
2627
Neo4jDriver,
2728
TRUST_ALL_CERTIFICATES,
@@ -58,7 +59,11 @@ def test_neo4j_driver_verify_connectivity(driver_info, test_script):
5859
with StubCluster(test_script):
5960
with GraphDatabase.driver(driver_info["uri_neo4j"], auth=driver_info["auth_token"], user_agent="test") as driver:
6061
assert isinstance(driver, Neo4jDriver)
61-
assert driver.verify_connectivity() is not None
62+
with pytest.warns(
63+
ExperimentalWarning,
64+
match="The configuration may change in the future."
65+
):
66+
assert driver.verify_connectivity() is not None
6267

6368

6469
# @pytest.mark.skip(reason="Flaky")
@@ -75,4 +80,8 @@ def test_neo4j_driver_verify_connectivity_server_down(driver_info, test_script):
7580
assert isinstance(driver, Neo4jDriver)
7681

7782
with pytest.raises(ServiceUnavailable):
78-
driver.verify_connectivity()
83+
with pytest.warns(
84+
ExperimentalWarning,
85+
match="The configuration may change in the future."
86+
):
87+
driver.verify_connectivity()

0 commit comments

Comments
 (0)