diff --git a/neo4j/__init__.py b/neo4j/__init__.py index 51812e5c7..cca775073 100644 --- a/neo4j/__init__.py +++ b/neo4j/__init__.py @@ -21,8 +21,6 @@ __all__ = [ "__version__", - "READ_ACCESS", - "WRITE_ACCESS", "GraphDatabase", "Driver", "BoltDriver", @@ -32,18 +30,50 @@ ] from logging import getLogger -from urllib.parse import urlparse, parse_qs - -from neo4j.addressing import Address -from neo4j.api import * -from neo4j.conf import Config, PoolConfig +from urllib.parse import ( + urlparse, + parse_qs, +) + +from neo4j.addressing import ( + Address, + IPv4Address, + IPv6Address, +) +from neo4j.api import ( + Auth, + AuthToken, + basic_auth, + kerberos_auth, + custom_auth, + Bookmark, + ServerInfo, + Version, + READ_ACCESS, + WRITE_ACCESS, +) +from neo4j.conf import ( + Config, + PoolConfig, +) +from neo4j.meta import ( + experimental, + get_user_agent, + version as __version__, +) +from neo4j.data import ( + Record, +) +from neo4j.work.simple import ( + Transaction, + Result, + ResultSummary, + Query, + Session, + SessionConfig, + unit_of_work, +) from neo4j.exceptions import ServiceUnavailable -from neo4j.meta import experimental, get_user_agent, version as __version__ - - -READ_ACCESS = "READ" -WRITE_ACCESS = "WRITE" - log = getLogger("neo4j") diff --git a/neo4j/api.py b/neo4j/api.py index 276b24186..c8fbe3823 100644 --- a/neo4j/api.py +++ b/neo4j/api.py @@ -159,3 +159,7 @@ def from_bytes(cls, b): if b[0] != 0 or b[1] != 0: raise ValueError("First two bytes must contain zero") return Version(b[-1], b[-2]) + + +READ_ACCESS = "READ" +WRITE_ACCESS = "WRITE" \ No newline at end of file diff --git a/neo4j/io/__init__.py b/neo4j/io/__init__.py index 2933248b4..1a84fe601 100644 --- a/neo4j/io/__init__.py +++ b/neo4j/io/__init__.py @@ -662,7 +662,7 @@ def ensure_routing_table_is_fresh(self, access_mode): :return: `True` if an update was required, `False` otherwise. """ - from neo4j import READ_ACCESS + from neo4j.api import READ_ACCESS if self.routing_table.is_fresh(readonly=(access_mode == READ_ACCESS)): return False with self.refresh_lock: @@ -676,7 +676,7 @@ def ensure_routing_table_is_fresh(self, access_mode): return True def _select_address(self, access_mode=None): - from neo4j import READ_ACCESS + from neo4j.api import READ_ACCESS """ Selects the address with the fewest in-use connections. """ self.ensure_routing_table_is_fresh(access_mode) @@ -695,7 +695,8 @@ def _select_address(self, access_mode=None): return choice(addresses_by_usage[min(addresses_by_usage)]) def acquire(self, access_mode=None, timeout=None): - from neo4j import READ_ACCESS, WRITE_ACCESS + from neo4j.api import WRITE_ACCESS + from neo4j.api import READ_ACCESS if access_mode is None: access_mode = WRITE_ACCESS if access_mode not in (READ_ACCESS, WRITE_ACCESS): diff --git a/neo4j/time/hydration.py b/neo4j/time/hydration.py index 198fc4305..d464490d6 100644 --- a/neo4j/time/hydration.py +++ b/neo4j/time/hydration.py @@ -19,17 +19,32 @@ # limitations under the License. -from datetime import time, datetime, timedelta - -from pytz import FixedOffset, timezone, utc +from datetime import ( + time, + datetime, + timedelta, +) from neo4j.packstream import Structure -from neo4j.time import Duration, Date, Time, DateTime +from neo4j.time import ( + Duration, + Date, + Time, + DateTime, +) + + +def get_date_unix_epoch(): + return Date(1970, 1, 1) + + +def get_date_unix_epoch_ordinal(): + return get_date_unix_epoch().to_ordinal() -UNIX_EPOCH_DATE = Date(1970, 1, 1) -UNIX_EPOCH_DATE_ORDINAL = UNIX_EPOCH_DATE.to_ordinal() -UNIX_EPOCH_DATETIME_UTC = DateTime(1970, 1, 1, 0, 0, 0, utc) +def get_datetime_unix_epoch_utc(): + from pytz import utc + return DateTime(1970, 1, 1, 0, 0, 0, utc) def hydrate_date(days): @@ -38,7 +53,7 @@ def hydrate_date(days): :param days: :return: Date """ - return Date.from_ordinal(UNIX_EPOCH_DATE_ORDINAL + days) + return Date.from_ordinal(get_date_unix_epoch_ordinal() + days) def dehydrate_date(value): @@ -48,7 +63,7 @@ def dehydrate_date(value): :type value: Date :return: """ - return Structure(b"D", value.toordinal() - UNIX_EPOCH_DATE.toordinal()) + return Structure(b"D", value.toordinal() - get_date_unix_epoch().toordinal()) def hydrate_time(nanoseconds, tz=None): @@ -58,6 +73,7 @@ def hydrate_time(nanoseconds, tz=None): :param tz: :return: Time """ + from pytz import FixedOffset seconds, nanoseconds = map(int, divmod(nanoseconds, 1000000000)) minutes, seconds = map(int, divmod(seconds, 60)) hours, minutes = map(int, divmod(minutes, 60)) @@ -98,11 +114,12 @@ def hydrate_datetime(seconds, nanoseconds, tz=None): :param tz: :return: datetime """ + from pytz import FixedOffset, timezone minutes, seconds = map(int, divmod(seconds, 60)) hours, minutes = map(int, divmod(minutes, 60)) days, hours = map(int, divmod(hours, 24)) seconds = (1000000000 * seconds + nanoseconds) / 1000000000 - t = DateTime.combine(Date.from_ordinal(UNIX_EPOCH_DATE_ORDINAL + days), Time(hours, minutes, seconds)) + t = DateTime.combine(Date.from_ordinal(get_date_unix_epoch_ordinal() + days), Time(hours, minutes, seconds)) if tz is None: return t if isinstance(tz, int): @@ -131,6 +148,7 @@ def seconds_and_nanoseconds(dt): tz = value.tzinfo if tz is None: # without time zone + from pytz import utc value = utc.localize(value) seconds, nanoseconds = seconds_and_nanoseconds(value) return Structure(b"d", seconds, nanoseconds) diff --git a/neo4j/work/simple.py b/neo4j/work/simple.py index 08ad00ffc..d0b6d7f5f 100644 --- a/neo4j/work/simple.py +++ b/neo4j/work/simple.py @@ -25,7 +25,7 @@ from time import perf_counter, sleep from warnings import warn -from neo4j import READ_ACCESS, WRITE_ACCESS +from neo4j.api import READ_ACCESS, WRITE_ACCESS from neo4j.conf import DeprecatedAlias from neo4j.data import DataHydrator, DataDehydrator from neo4j.exceptions import ( diff --git a/tests/integration/test_bookmarking.py b/tests/integration/test_bookmarking.py index eabbed66f..0679186a7 100644 --- a/tests/integration/test_bookmarking.py +++ b/tests/integration/test_bookmarking.py @@ -21,7 +21,7 @@ from uuid import uuid4 -from neo4j import WRITE_ACCESS, READ_ACCESS +from neo4j.api import READ_ACCESS, WRITE_ACCESS from neo4j.graph import Node diff --git a/tests/stub/test_bookmarking.py b/tests/stub/test_bookmarking.py index 344e713bf..74a77a2bb 100644 --- a/tests/stub/test_bookmarking.py +++ b/tests/stub/test_bookmarking.py @@ -23,8 +23,8 @@ from neo4j import ( GraphDatabase, - READ_ACCESS, ) +from neo4j.api import READ_ACCESS from tests.stub.conftest import StubCluster diff --git a/tests/stub/test_routingdriver.py b/tests/stub/test_routingdriver.py index 7768a0022..7937f3327 100644 --- a/tests/stub/test_routingdriver.py +++ b/tests/stub/test_routingdriver.py @@ -23,10 +23,9 @@ from neo4j import ( GraphDatabase, - READ_ACCESS, - WRITE_ACCESS, Neo4jDriver, ) +from neo4j.api import READ_ACCESS, WRITE_ACCESS from neo4j._exceptions import BoltRoutingError diff --git a/tests/unit/test_import_neo4j.py b/tests/unit/test_import_neo4j.py new file mode 100644 index 000000000..6b8bb89a2 --- /dev/null +++ b/tests/unit/test_import_neo4j.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- + +# Copyright (c) 2002-2020 "Neo4j," +# Neo4j Sweden AB [http://neo4j.com] +# +# This file is part of Neo4j. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import pytest + +# python -m pytest tests/unit/test_import_neo4j.py -s -v + + +def test_import_dunder_version(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_dunder_version + from neo4j import __version__ + + +def test_import_graphdatabase(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_graphdatabase + from neo4j import GraphDatabase + + +def test_import_driver(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_driver + from neo4j import Driver + + +def test_import_boltdriver(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_boltdriver + from neo4j import BoltDriver + + +def test_import_neo4jdriver(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_neo4jdriver + from neo4j import Neo4jDriver + + +def test_import_auth(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_auth + from neo4j import Auth + + +def test_import_authtoken(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_authtoken + from neo4j import AuthToken + + +def test_import_basic_auth(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_auth + from neo4j import basic_auth + + +def test_import_kerberos_auth(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_kerberos_auth + from neo4j import kerberos_auth + + +def test_import_custom_auth(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_custom_auth + from neo4j import custom_auth + + +def test_import_read_access(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_read_access + from neo4j import READ_ACCESS + + +def test_import_write_access(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_write_access + from neo4j import WRITE_ACCESS + + +def test_import_transaction(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_transaction + from neo4j import Transaction + + +def test_import_record(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_record + from neo4j import Record + + +def test_import_session(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_session + from neo4j import Session + + +def test_import_sessionconfig(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_sessionconfig + from neo4j import SessionConfig + + +def test_import_query(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_query + from neo4j import Query + + +def test_import_result(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_result + from neo4j import Result + + +def test_import_resultsummary(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_resultsummary + from neo4j import ResultSummary + + +def test_import_unit_of_work(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_unit_of_work + from neo4j import unit_of_work + + +def test_import_config(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_config + from neo4j import Config + + +def test_import_poolconfig(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_poolconfig + from neo4j import PoolConfig + + +def test_import_graph(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_graph + import neo4j.graph as graph + + +def test_import_graph_node(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_graph_node + from neo4j.graph import Node + + +def test_import_graph_Path(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_graph_Path + from neo4j.graph import Path + + +def test_import_graph_graph(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_graph_graph + from neo4j.graph import Graph + + +def test_import_spatial(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_spatial + import neo4j.spatial as spatial + + +def test_import_time(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_time + import neo4j.time as time + + +def test_import_exceptions(): + # python -m pytest tests/unit/test_import_neo4j.py -s -v -k test_import_exceptions + import neo4j.exceptions as exceptions + +