diff --git a/CHANGELOG.md b/CHANGELOG.md index 993b07880..020626404 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ See also https://github.com/neo4j/neo4j-python-driver/wiki for more details. ## NEXT RELEASE -- ... +- Renamed experimental `neo4j.RoutingControl.READERS` to `READ` and `WRITERS` to `WRITE`. +- Renamed experimental `driver.query_bookmark_manager` to `execute_query_bookmark_manager`. ## Version 5.7 diff --git a/docs/source/api.rst b/docs/source/api.rst index 5ae6ff113..93a92c169 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -164,7 +164,7 @@ Closing a driver will immediately shut down all connections in the pool. verify_connectivity, get_server_info, verify_authentication, supports_session_auth, supports_multi_db - .. method:: execute_query(query, parameters_=None,routing_=neo4j.RoutingControl.WRITERS, database_=None, impersonated_user_=None, bookmark_manager_=self.query_bookmark_manager, result_transformer_=Result.to_eager_result, **kwargs) + .. method:: execute_query(query, parameters_=None,routing_=neo4j.RoutingControl.WRITE, database_=None, impersonated_user_=None, bookmark_manager_=self.query_bookmark_manager, result_transformer_=Result.to_eager_result, **kwargs) Execute a query in a transaction function and return all results. @@ -194,9 +194,9 @@ Closing a driver will immediately shut down all connections in the pool. bookmark_manager=bookmark_manager_, auth=auth_, ) as session: - if routing_ == RoutingControl.WRITERS: + if routing_ == RoutingControl.WRITE: return session.execute_write(work) - elif routing_ == RoutingControl.READERS: + elif routing_ == RoutingControl.READ: return session.execute_read(work) Usage example:: @@ -211,7 +211,7 @@ Closing a driver will immediately shut down all connections in the pool. records, summary, keys = driver.execute_query( "MATCH (p:Person {age: $age}) RETURN p.name", {"age": 42}, - routing_=neo4j.RoutingControl.READERS, # or just "r" + routing_=neo4j.RoutingControl.READ, # or just "r" database_="neo4j", ) assert keys == ["p.name"] # not needed, just for illustration @@ -232,7 +232,7 @@ Closing a driver will immediately shut down all connections in the pool. "SET p.nickname = 'My dear' " "RETURN count(*)", # optional routing parameter, as write is default - # routing_=neo4j.RoutingControl.WRITERS, # or just "w", + # routing_=neo4j.RoutingControl.WRITE, # or just "w", database_="neo4j", result_transformer_=neo4j.Result.single, age=15, @@ -380,7 +380,8 @@ Closing a driver will immediately shut down all connections in the pool. .. versionadded:: 5.5 .. versionchanged:: 5.8 - Added the ``auth_`` parameter. + * Added the ``auth_`` parameter. + * Stabilized from experimental. .. _driver-configuration-ref: @@ -1022,8 +1023,7 @@ See :class:`.BookmarkManager` for more information. .. versionadded:: 5.0 -**This is experimental** (see :ref:`filter-warnings-ref`). -It might be changed or removed any time even without prior notice. +.. versionchanged:: 5.8 stabilized from experimental .. _session-auth-ref: diff --git a/docs/source/async_api.rst b/docs/source/async_api.rst index 35e08a137..c29d1227c 100644 --- a/docs/source/async_api.rst +++ b/docs/source/async_api.rst @@ -153,7 +153,7 @@ Closing a driver will immediately shut down all connections in the pool. verify_connectivity, get_server_info, verify_authentication, supports_session_auth, supports_multi_db - .. method:: execute_query(query, parameters_=None, routing_=neo4j.RoutingControl.WRITERS, database_=None, impersonated_user_=None, bookmark_manager_=self.query_bookmark_manager, result_transformer_=AsyncResult.to_eager_result, **kwargs) + .. method:: execute_query(query, parameters_=None, routing_=neo4j.RoutingControl.WRITE, database_=None, impersonated_user_=None, bookmark_manager_=self.query_bookmark_manager, result_transformer_=AsyncResult.to_eager_result, **kwargs) :async: Execute a query in a transaction function and return all results. @@ -184,9 +184,9 @@ Closing a driver will immediately shut down all connections in the pool. bookmark_manager=bookmark_manager_, auth=auth_, ) as session: - if routing_ == RoutingControl.WRITERS: + if routing_ == RoutingControl.WRITE: return await session.execute_write(work) - elif routing_ == RoutingControl.READERS: + elif routing_ == RoutingControl.READ: return await session.execute_read(work) Usage example:: @@ -201,7 +201,7 @@ Closing a driver will immediately shut down all connections in the pool. records, summary, keys = await driver.execute_query( "MATCH (p:Person {age: $age}) RETURN p.name", {"age": 42}, - routing_=neo4j.RoutingControl.READERS, # or just "r" + routing_=neo4j.RoutingControl.READ, # or just "r" database_="neo4j", ) assert keys == ["p.name"] # not needed, just for illustration @@ -222,7 +222,7 @@ Closing a driver will immediately shut down all connections in the pool. "SET p.nickname = 'My dear' " "RETURN count(*)", # optional routing parameter, as write is default - # routing_=neo4j.RoutingControl.WRITERS, # or just "w", + # routing_=neo4j.RoutingControl.WRITE, # or just "w", database_="neo4j", result_transformer_=neo4j.AsyncResult.single, age=15, @@ -360,17 +360,11 @@ Closing a driver will immediately shut down all connections in the pool. :returns: the result of the ``result_transformer`` :rtype: T - **This is experimental** (see :ref:`filter-warnings-ref`). - It might be changed or removed any time even without prior notice. - - We are looking for feedback on this feature. Please let us know what - you think about it here: - https://github.com/neo4j/neo4j-python-driver/discussions/896 - .. versionadded:: 5.5 .. versionchanged:: 5.8 - Added the ``auth_`` parameter. + * Added the ``auth_`` parameter. + * Stabilized from experimental. .. _async-driver-configuration-ref: @@ -659,8 +653,7 @@ See :class:`BookmarkManager` for more information. :Type: :data:`None`, :class:`BookmarkManager`, or :class:`AsyncBookmarkManager` :Default: :data:`None` -**This is experimental** (see :ref:`filter-warnings-ref`). -It might be changed or removed any time even without prior notice. +.. versionchanged:: 5.8 stabilized from experimental diff --git a/src/neo4j/_api.py b/src/neo4j/_api.py index f42c189d5..c833c0b32 100644 --- a/src/neo4j/_api.py +++ b/src/neo4j/_api.py @@ -208,21 +208,22 @@ class RoutingControl(str, Enum): Inherits from :class:`str` and :class:`Enum`. Every driver API accepting a :class:`.RoutingControl` value will also accept a string - >>> RoutingControl.READERS == "r" + >>> RoutingControl.READ == "r" True - >>> RoutingControl.WRITERS == "w" + >>> RoutingControl.WRITE == "w" True - **This is experimental.** - It might be changed or removed any time even without prior notice. - .. seealso:: :attr:`.AsyncDriver.execute_query`, :attr:`.Driver.execute_query` .. versionadded:: 5.5 + + .. versionchanged:: 5.8 + * renamed ``READERS`` to ``READ`` and ``WRITERS`` to ``WRITE`` + * stabilized from experimental """ - READERS = "r" - WRITERS = "w" + READ = "r" + WRITE = "w" if t.TYPE_CHECKING: diff --git a/src/neo4j/_async/auth_management.py b/src/neo4j/_async/auth_management.py index de6d0055f..6fe02d0a1 100644 --- a/src/neo4j/_async/auth_management.py +++ b/src/neo4j/_async/auth_management.py @@ -20,6 +20,7 @@ # work around for https://github.com/sphinx-doc/sphinx/pull/10880 # make sure TAuth is resolved in the docs, else they're pretty useless + import time import typing as t from logging import getLogger diff --git a/src/neo4j/_async/driver.py b/src/neo4j/_async/driver.py index 81180bb75..9bc682930 100644 --- a/src/neo4j/_async/driver.py +++ b/src/neo4j/_async/driver.py @@ -44,9 +44,7 @@ ) from .._meta import ( deprecation_warn, - experimental, experimental_warn, - ExperimentalWarning, preview, preview_warn, PreviewWarning, @@ -293,10 +291,6 @@ def driver( routing_context=routing_context, **config) @classmethod - @experimental( - "The bookmark manager feature is experimental. " - "It might be changed or removed any time even without prior notice." - ) def bookmark_manager( cls, initial_bookmarks: t.Union[None, Bookmarks, t.Iterable[str]] = None, @@ -357,9 +351,6 @@ def bookmark_manager( :returns: A default implementation of :class:`AsyncBookmarkManager`. - **This is experimental** (see :ref:`filter-warnings-ref`). - It might be changed or removed any time even without prior notice. - .. versionadded:: 5.0 .. versionchanged:: 5.3 @@ -373,6 +364,8 @@ def bookmark_manager( an argument. * ``bookmarks_consumer`` no longer receives the database name as an argument. + + .. versionchanged:: 5.8 stabilized from experimental """ return AsyncNeo4jBookmarkManager( initial_bookmarks=initial_bookmarks, @@ -480,12 +473,7 @@ def __init__(self, pool, default_workspace_config): assert default_workspace_config is not None self._pool = pool self._default_workspace_config = default_workspace_config - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message=r".*\bbookmark manager\b.*", - category=ExperimentalWarning) - self._query_bookmark_manager = \ - AsyncGraphDatabase.bookmark_manager() + self._query_bookmark_manager = AsyncGraphDatabase.bookmark_manager() async def __aenter__(self) -> AsyncDriver: return self @@ -579,7 +567,7 @@ async def execute_query( self, query_: str, parameters_: t.Optional[t.Dict[str, t.Any]] = None, - routing_: T_RoutingControl = RoutingControl.WRITERS, + routing_: T_RoutingControl = RoutingControl.WRITE, database_: t.Optional[str] = None, impersonated_user_: t.Optional[str] = None, bookmark_manager_: t.Union[ @@ -598,7 +586,7 @@ async def execute_query( self, query_: str, parameters_: t.Optional[t.Dict[str, t.Any]] = None, - routing_: T_RoutingControl = RoutingControl.WRITERS, + routing_: T_RoutingControl = RoutingControl.WRITE, database_: t.Optional[str] = None, impersonated_user_: t.Optional[str] = None, bookmark_manager_: t.Union[ @@ -612,15 +600,11 @@ async def execute_query( ) -> _T: ... - @experimental( - "Driver.execute_query is experimental. " - "It might be changed or removed any time even without prior notice." - ) async def execute_query( self, query_: str, parameters_: t.Optional[t.Dict[str, t.Any]] = None, - routing_: T_RoutingControl = RoutingControl.WRITERS, + routing_: T_RoutingControl = RoutingControl.WRITE, database_: t.Optional[str] = None, impersonated_user_: t.Optional[str] = None, bookmark_manager_: t.Union[ @@ -661,9 +645,9 @@ async def work(tx): bookmark_manager=bookmark_manager_, auth=auth_, ) as session: - if routing_ == RoutingControl.WRITERS: + if routing_ == RoutingControl.WRITE: return await session.execute_write(work) - elif routing_ == RoutingControl.READERS: + elif routing_ == RoutingControl.READ: return await session.execute_read(work) Usage example:: @@ -678,7 +662,7 @@ async def example(driver: neo4j.AsyncDriver) -> List[str]: records, summary, keys = await driver.execute_query( "MATCH (p:Person {age: $age}) RETURN p.name", {"age": 42}, - routing_=neo4j.RoutingControl.READERS, # or just "r" + routing_=neo4j.RoutingControl.READ, # or just "r" database_="neo4j", ) assert keys == ["p.name"] # not needed, just for illustration @@ -699,7 +683,7 @@ async def example(driver: neo4j.AsyncDriver) -> int: "SET p.nickname = 'My dear' " "RETURN count(*)", # optional routing parameter, as write is default - # routing_=neo4j.RoutingControl.WRITERS, # or just "w", + # routing_=neo4j.RoutingControl.WRITE, # or just "w", database_="neo4j", result_transformer_=neo4j.AsyncResult.single, age=15, @@ -837,17 +821,11 @@ async def example(driver: neo4j.AsyncDriver) -> neo4j.Record:: :returns: the result of the ``result_transformer`` :rtype: T - **This is experimental** (see :ref:`filter-warnings-ref`). - It might be changed or removed any time even without prior notice. - - We are looking for feedback on this feature. Please let us know what - you think about it here: - https://github.com/neo4j/neo4j-python-driver/discussions/896 - .. versionadded:: 5.5 .. versionchanged:: 5.8 - Added the ``auth_`` parameter. + * Added the ``auth_`` parameter. + * Stabilized from experimental. """ invalid_kwargs = [k for k in kwargs if k[-2:-1] != "_" and k[-1:] == "_"] @@ -866,9 +844,6 @@ async def example(driver: neo4j.AsyncDriver) -> neo4j.Record:: assert bookmark_manager_ is not _default with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message=r".*\bbookmark_manager\b.*", - category=ExperimentalWarning) warnings.filterwarnings("ignore", message=r"^User switching\b.*", category=PreviewWarning) @@ -877,9 +852,9 @@ async def example(driver: neo4j.AsyncDriver) -> neo4j.Record:: bookmark_manager=bookmark_manager_, auth=auth_) async with session: - if routing_ == RoutingControl.WRITERS: + if routing_ == RoutingControl.WRITE: executor = session.execute_write - elif routing_ == RoutingControl.READERS: + elif routing_ == RoutingControl.READ: executor = session.execute_read else: raise ValueError("Invalid routing control value: %r" @@ -889,11 +864,7 @@ async def example(driver: neo4j.AsyncDriver) -> neo4j.Record:: ) @property - @experimental( - "Driver.query_bookmark_manager is experimental. " - "It might be changed or removed any time even without prior notice." - ) - def query_bookmark_manager(self) -> AsyncBookmarkManager: + def execute_query_bookmark_manager(self) -> AsyncBookmarkManager: """The driver's default query bookmark manager. This is the default :class:`AsyncBookmarkManager` used by @@ -912,10 +883,12 @@ async def example(driver: neo4j.AsyncDriver) -> None: # (i.e., can read what was written by ) await driver.execute_query("") - **This is experimental** (see :ref:`filter-warnings-ref`). - It might be changed or removed any time even without prior notice. - .. versionadded:: 5.5 + + .. versionchanged:: 5.8 + * Renamed from ``query_bookmark_manager`` to + ``execute_query_bookmark_manager``. + * Stabilized from experimental. """ return self._query_bookmark_manager @@ -1212,11 +1185,7 @@ async def _work( ) -> _T: res = await tx.run(query, parameters) if transformer is AsyncResult.to_eager_result: - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message=r".*\bto_eager_result\b.*", - category=ExperimentalWarning) - return await transformer(res) + return await transformer(res) return await transformer(res) diff --git a/src/neo4j/_async/work/result.py b/src/neo4j/_async/work/result.py index 5a8dea972..fe8629d66 100644 --- a/src/neo4j/_async/work/result.py +++ b/src/neo4j/_async/work/result.py @@ -19,10 +19,7 @@ from __future__ import annotations import typing as t -from collections import ( - deque, - namedtuple, -) +from collections import deque from warnings import warn @@ -35,7 +32,6 @@ Record, RecordTableRowExporter, ) -from ..._meta import experimental from ..._work import ( EagerResult, ResultSummary, @@ -608,10 +604,6 @@ async def data(self, *keys: _TResultKey) -> t.List[t.Dict[str, t.Any]]: """ return [record.data(*keys) async for record in self] - @experimental( - "Result.to_eager_result is experimental. " - "It might be changed or removed any time even without prior notice." - ) async def to_eager_result(self) -> EagerResult: """Convert this result to an :class:`.EagerResult`. @@ -624,10 +616,9 @@ async def to_eager_result(self) -> EagerResult: was obtained has been closed or the Result has been explicitly consumed. - **This is experimental** (see :ref:`filter-warnings-ref`). - It might be changed or removed any time even without prior notice. - .. versionadded:: 5.5 + + .. versionchanged:: 5.8 stabilized from experimental """ await self._buffer_all() diff --git a/src/neo4j/_async_compat/util.py b/src/neo4j/_async_compat/util.py index 53771edf2..f7027926c 100644 --- a/src/neo4j/_async_compat/util.py +++ b/src/neo4j/_async_compat/util.py @@ -23,8 +23,6 @@ import typing as t from functools import wraps -from .._meta import experimental - if t.TYPE_CHECKING: import typing_extensions as te diff --git a/src/neo4j/_auth_management.py b/src/neo4j/_auth_management.py index 6d3c7a928..69bfcec8c 100644 --- a/src/neo4j/_auth_management.py +++ b/src/neo4j/_auth_management.py @@ -20,6 +20,7 @@ # work around for https://github.com/sphinx-doc/sphinx/pull/10880 # make sure TAuth is resolved in the docs, else they're pretty useless + import abc import typing as t from dataclasses import dataclass diff --git a/src/neo4j/_conf.py b/src/neo4j/_conf.py index 61b6f6760..d00b21d98 100644 --- a/src/neo4j/_conf.py +++ b/src/neo4j/_conf.py @@ -500,7 +500,7 @@ class WorkspaceConfig(Config): # Note that you need appropriate permissions to do so. #: Bookmark Manager - bookmark_manager = ExperimentalOption(None) + bookmark_manager = None # Specify the bookmark manager to be used for sessions by default. diff --git a/src/neo4j/_sync/auth_management.py b/src/neo4j/_sync/auth_management.py index fc016f4b2..4513860a7 100644 --- a/src/neo4j/_sync/auth_management.py +++ b/src/neo4j/_sync/auth_management.py @@ -20,6 +20,7 @@ # work around for https://github.com/sphinx-doc/sphinx/pull/10880 # make sure TAuth is resolved in the docs, else they're pretty useless + import time import typing as t from logging import getLogger diff --git a/src/neo4j/_sync/driver.py b/src/neo4j/_sync/driver.py index 69ccc9048..769c9dfe6 100644 --- a/src/neo4j/_sync/driver.py +++ b/src/neo4j/_sync/driver.py @@ -44,9 +44,7 @@ ) from .._meta import ( deprecation_warn, - experimental, experimental_warn, - ExperimentalWarning, preview, preview_warn, PreviewWarning, @@ -292,10 +290,6 @@ def driver( routing_context=routing_context, **config) @classmethod - @experimental( - "The bookmark manager feature is experimental. " - "It might be changed or removed any time even without prior notice." - ) def bookmark_manager( cls, initial_bookmarks: t.Union[None, Bookmarks, t.Iterable[str]] = None, @@ -356,9 +350,6 @@ def bookmark_manager( :returns: A default implementation of :class:`BookmarkManager`. - **This is experimental** (see :ref:`filter-warnings-ref`). - It might be changed or removed any time even without prior notice. - .. versionadded:: 5.0 .. versionchanged:: 5.3 @@ -372,6 +363,8 @@ def bookmark_manager( an argument. * ``bookmarks_consumer`` no longer receives the database name as an argument. + + .. versionchanged:: 5.8 stabilized from experimental """ return Neo4jBookmarkManager( initial_bookmarks=initial_bookmarks, @@ -479,12 +472,7 @@ def __init__(self, pool, default_workspace_config): assert default_workspace_config is not None self._pool = pool self._default_workspace_config = default_workspace_config - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message=r".*\bbookmark manager\b.*", - category=ExperimentalWarning) - self._query_bookmark_manager = \ - GraphDatabase.bookmark_manager() + self._query_bookmark_manager = GraphDatabase.bookmark_manager() def __enter__(self) -> Driver: return self @@ -578,7 +566,7 @@ def execute_query( self, query_: str, parameters_: t.Optional[t.Dict[str, t.Any]] = None, - routing_: T_RoutingControl = RoutingControl.WRITERS, + routing_: T_RoutingControl = RoutingControl.WRITE, database_: t.Optional[str] = None, impersonated_user_: t.Optional[str] = None, bookmark_manager_: t.Union[ @@ -597,7 +585,7 @@ def execute_query( self, query_: str, parameters_: t.Optional[t.Dict[str, t.Any]] = None, - routing_: T_RoutingControl = RoutingControl.WRITERS, + routing_: T_RoutingControl = RoutingControl.WRITE, database_: t.Optional[str] = None, impersonated_user_: t.Optional[str] = None, bookmark_manager_: t.Union[ @@ -611,15 +599,11 @@ def execute_query( ) -> _T: ... - @experimental( - "Driver.execute_query is experimental. " - "It might be changed or removed any time even without prior notice." - ) def execute_query( self, query_: str, parameters_: t.Optional[t.Dict[str, t.Any]] = None, - routing_: T_RoutingControl = RoutingControl.WRITERS, + routing_: T_RoutingControl = RoutingControl.WRITE, database_: t.Optional[str] = None, impersonated_user_: t.Optional[str] = None, bookmark_manager_: t.Union[ @@ -660,9 +644,9 @@ def work(tx): bookmark_manager=bookmark_manager_, auth=auth_, ) as session: - if routing_ == RoutingControl.WRITERS: + if routing_ == RoutingControl.WRITE: return session.execute_write(work) - elif routing_ == RoutingControl.READERS: + elif routing_ == RoutingControl.READ: return session.execute_read(work) Usage example:: @@ -677,7 +661,7 @@ def example(driver: neo4j.Driver) -> List[str]: records, summary, keys = driver.execute_query( "MATCH (p:Person {age: $age}) RETURN p.name", {"age": 42}, - routing_=neo4j.RoutingControl.READERS, # or just "r" + routing_=neo4j.RoutingControl.READ, # or just "r" database_="neo4j", ) assert keys == ["p.name"] # not needed, just for illustration @@ -698,7 +682,7 @@ def example(driver: neo4j.Driver) -> int: "SET p.nickname = 'My dear' " "RETURN count(*)", # optional routing parameter, as write is default - # routing_=neo4j.RoutingControl.WRITERS, # or just "w", + # routing_=neo4j.RoutingControl.WRITE, # or just "w", database_="neo4j", result_transformer_=neo4j.Result.single, age=15, @@ -836,17 +820,11 @@ def example(driver: neo4j.Driver) -> neo4j.Record:: :returns: the result of the ``result_transformer`` :rtype: T - **This is experimental** (see :ref:`filter-warnings-ref`). - It might be changed or removed any time even without prior notice. - - We are looking for feedback on this feature. Please let us know what - you think about it here: - https://github.com/neo4j/neo4j-python-driver/discussions/896 - .. versionadded:: 5.5 .. versionchanged:: 5.8 - Added the ``auth_`` parameter. + * Added the ``auth_`` parameter. + * Stabilized from experimental. """ invalid_kwargs = [k for k in kwargs if k[-2:-1] != "_" and k[-1:] == "_"] @@ -865,9 +843,6 @@ def example(driver: neo4j.Driver) -> neo4j.Record:: assert bookmark_manager_ is not _default with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message=r".*\bbookmark_manager\b.*", - category=ExperimentalWarning) warnings.filterwarnings("ignore", message=r"^User switching\b.*", category=PreviewWarning) @@ -876,9 +851,9 @@ def example(driver: neo4j.Driver) -> neo4j.Record:: bookmark_manager=bookmark_manager_, auth=auth_) with session: - if routing_ == RoutingControl.WRITERS: + if routing_ == RoutingControl.WRITE: executor = session.execute_write - elif routing_ == RoutingControl.READERS: + elif routing_ == RoutingControl.READ: executor = session.execute_read else: raise ValueError("Invalid routing control value: %r" @@ -888,11 +863,7 @@ def example(driver: neo4j.Driver) -> neo4j.Record:: ) @property - @experimental( - "Driver.query_bookmark_manager is experimental. " - "It might be changed or removed any time even without prior notice." - ) - def query_bookmark_manager(self) -> BookmarkManager: + def execute_query_bookmark_manager(self) -> BookmarkManager: """The driver's default query bookmark manager. This is the default :class:`BookmarkManager` used by @@ -911,10 +882,12 @@ def example(driver: neo4j.Driver) -> None: # (i.e., can read what was written by ) driver.execute_query("") - **This is experimental** (see :ref:`filter-warnings-ref`). - It might be changed or removed any time even without prior notice. - .. versionadded:: 5.5 + + .. versionchanged:: 5.8 + * Renamed from ``query_bookmark_manager`` to + ``execute_query_bookmark_manager``. + * Stabilized from experimental. """ return self._query_bookmark_manager @@ -1211,11 +1184,7 @@ def _work( ) -> _T: res = tx.run(query, parameters) if transformer is Result.to_eager_result: - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message=r".*\bto_eager_result\b.*", - category=ExperimentalWarning) - return transformer(res) + return transformer(res) return transformer(res) diff --git a/src/neo4j/_sync/work/result.py b/src/neo4j/_sync/work/result.py index cfc6df059..d41c452f1 100644 --- a/src/neo4j/_sync/work/result.py +++ b/src/neo4j/_sync/work/result.py @@ -19,10 +19,7 @@ from __future__ import annotations import typing as t -from collections import ( - deque, - namedtuple, -) +from collections import deque from warnings import warn @@ -35,7 +32,6 @@ Record, RecordTableRowExporter, ) -from ..._meta import experimental from ..._work import ( EagerResult, ResultSummary, @@ -608,10 +604,6 @@ def data(self, *keys: _TResultKey) -> t.List[t.Dict[str, t.Any]]: """ return [record.data(*keys) for record in self] - @experimental( - "Result.to_eager_result is experimental. " - "It might be changed or removed any time even without prior notice." - ) def to_eager_result(self) -> EagerResult: """Convert this result to an :class:`.EagerResult`. @@ -624,10 +616,9 @@ def to_eager_result(self) -> EagerResult: was obtained has been closed or the Result has been explicitly consumed. - **This is experimental** (see :ref:`filter-warnings-ref`). - It might be changed or removed any time even without prior notice. - .. versionadded:: 5.5 + + .. versionchanged:: 5.8 stabilized from experimental """ self._buffer_all() diff --git a/src/neo4j/_work/eager_result.py b/src/neo4j/_work/eager_result.py index d88e23f50..5e7aaa248 100644 --- a/src/neo4j/_work/eager_result.py +++ b/src/neo4j/_work/eager_result.py @@ -33,9 +33,6 @@ class EagerResult(t.NamedTuple): * keys - the list of keys returned by the query (see :attr:`AsyncResult.keys` and :attr:`.Result.keys`) - **This is experimental** (see :ref:`filter-warnings-ref`). - It might be changed or removed any time even without prior notice. - .. seealso:: :attr:`.AsyncDriver.execute_query`, :attr:`.Driver.execute_query` Which by default return an instance of this class. @@ -44,6 +41,8 @@ class EagerResult(t.NamedTuple): Which can be used to convert to instance of this class. .. versionadded:: 5.5 + + .. versionchanged:: 5.8 stabilized from experimental """ #: Alias for field 0 (``eager_result[0]``) records: t.List[Record] diff --git a/src/neo4j/api.py b/src/neo4j/api.py index c5d94a332..457cadc54 100644 --- a/src/neo4j/api.py +++ b/src/neo4j/api.py @@ -15,9 +15,11 @@ # See the License for the specific language governing permissions and # limitations under the License. + """ Base classes and helpers. """ + from __future__ import annotations import abc @@ -408,9 +410,6 @@ class BookmarkManager(_Protocol, metaclass=abc.ABCMeta): .. note:: All methods must be concurrency safe. - **This is experimental.** - It might be changed or removed any time even without prior notice. - .. versionadded:: 5.0 .. versionchanged:: 5.3 @@ -422,6 +421,8 @@ class BookmarkManager(_Protocol, metaclass=abc.ABCMeta): * :meth:`.get_bookmarks` has no longer a ``database`` argument. * The ``get_all_bookmarks`` method was removed. * The ``forget`` method was removed. + + .. versionchanged:: 5.8 stabilized from experimental """ @abc.abstractmethod @@ -453,13 +454,12 @@ class AsyncBookmarkManager(_Protocol, metaclass=abc.ABCMeta): The driver comes with a default implementation of the async bookmark manager accessible through :attr:`.AsyncGraphDatabase.bookmark_manager()`. - **This is experimental.** - It might be changed or removed any time even without prior notice. - .. versionadded:: 5.0 .. versionchanged:: 5.3 See :class:`.BookmarkManager` for changes. + + .. versionchanged:: 5.8 stabilized from experimental """ @abc.abstractmethod diff --git a/testkitbackend/_async/requests.py b/testkitbackend/_async/requests.py index 4653a488d..af2c4da17 100644 --- a/testkitbackend/_async/requests.py +++ b/testkitbackend/_async/requests.py @@ -351,12 +351,7 @@ async def ExecuteQuery(backend, data): bookmark_manager = backend.bookmark_managers[bookmark_manager_id] kwargs["bookmark_manager_"] = bookmark_manager - with warning_check( - neo4j.ExperimentalWarning, - "Driver.execute_query is experimental. " - "It might be changed or removed any time even without prior notice." - ): - eager_result = await driver.execute_query(cypher, params, **kwargs) + eager_result = await driver.execute_query(cypher, params, **kwargs) await backend.send_response("EagerResult", { "keys": eager_result.keys, "records": list(map(totestkit.record, eager_result.records)), @@ -441,14 +436,7 @@ async def NewBookmarkManager(backend, data): backend, bookmark_manager_id ) - with warning_check( - neo4j.ExperimentalWarning, - "The bookmark manager feature is experimental. It might be changed or " - "removed any time even without prior notice." - ): - bookmark_manager = neo4j.AsyncGraphDatabase.bookmark_manager( - **bmm_kwargs - ) + bookmark_manager = neo4j.AsyncGraphDatabase.bookmark_manager(**bmm_kwargs) backend.bookmark_managers[bookmark_manager_id] = bookmark_manager await backend.send_response("BookmarkManager", {"id": bookmark_manager_id}) @@ -556,11 +544,6 @@ async def NewSession(backend, data): config["bookmark_manager"] = backend.bookmark_managers[ data["bookmarkManagerId"] ] - expected_warnings.append(( - neo4j.ExperimentalWarning, - "The 'bookmark_manager' config key is experimental. It might be " - "changed or removed any time even without prior notice." - )) for (conf_name, data_name) in ( ("fetch_size", "fetchSize"), ("impersonated_user", "impersonatedUser"), diff --git a/testkitbackend/_sync/requests.py b/testkitbackend/_sync/requests.py index a70bbc65b..f1ad1859f 100644 --- a/testkitbackend/_sync/requests.py +++ b/testkitbackend/_sync/requests.py @@ -351,12 +351,7 @@ def ExecuteQuery(backend, data): bookmark_manager = backend.bookmark_managers[bookmark_manager_id] kwargs["bookmark_manager_"] = bookmark_manager - with warning_check( - neo4j.ExperimentalWarning, - "Driver.execute_query is experimental. " - "It might be changed or removed any time even without prior notice." - ): - eager_result = driver.execute_query(cypher, params, **kwargs) + eager_result = driver.execute_query(cypher, params, **kwargs) backend.send_response("EagerResult", { "keys": eager_result.keys, "records": list(map(totestkit.record, eager_result.records)), @@ -441,14 +436,7 @@ def NewBookmarkManager(backend, data): backend, bookmark_manager_id ) - with warning_check( - neo4j.ExperimentalWarning, - "The bookmark manager feature is experimental. It might be changed or " - "removed any time even without prior notice." - ): - bookmark_manager = neo4j.GraphDatabase.bookmark_manager( - **bmm_kwargs - ) + bookmark_manager = neo4j.GraphDatabase.bookmark_manager(**bmm_kwargs) backend.bookmark_managers[bookmark_manager_id] = bookmark_manager backend.send_response("BookmarkManager", {"id": bookmark_manager_id}) @@ -556,11 +544,6 @@ def NewSession(backend, data): config["bookmark_manager"] = backend.bookmark_managers[ data["bookmarkManagerId"] ] - expected_warnings.append(( - neo4j.ExperimentalWarning, - "The 'bookmark_manager' config key is experimental. It might be " - "changed or removed any time even without prior notice." - )) for (conf_name, data_name) in ( ("fetch_size", "fetchSize"), ("impersonated_user", "impersonatedUser"), diff --git a/tests/unit/async_/io/test_class_bolt5x1.py b/tests/unit/async_/io/test_class_bolt5x1.py index 83dab776b..ab4855d96 100644 --- a/tests/unit/async_/io/test_class_bolt5x1.py +++ b/tests/unit/async_/io/test_class_bolt5x1.py @@ -24,7 +24,6 @@ import neo4j.exceptions from neo4j._async.io._bolt5 import AsyncBolt5x1 from neo4j._conf import PoolConfig -from neo4j.auth_management import AsyncAuthManagers from neo4j.exceptions import ConfigurationError from ...._async_compat import mark_async_test diff --git a/tests/unit/async_/io/test_class_bolt5x2.py b/tests/unit/async_/io/test_class_bolt5x2.py index 676eb5b9b..7c9a2064c 100644 --- a/tests/unit/async_/io/test_class_bolt5x2.py +++ b/tests/unit/async_/io/test_class_bolt5x2.py @@ -24,7 +24,6 @@ import neo4j from neo4j._async.io._bolt5 import AsyncBolt5x2 from neo4j._conf import PoolConfig -from neo4j.auth_management import AsyncAuthManagers from ...._async_compat import mark_async_test diff --git a/tests/unit/async_/test_bookmark_manager.py b/tests/unit/async_/test_bookmark_manager.py index a24ac2539..c5800d8d5 100644 --- a/tests/unit/async_/test_bookmark_manager.py +++ b/tests/unit/async_/test_bookmark_manager.py @@ -36,8 +36,7 @@ @copy_signature(neo4j.AsyncGraphDatabase.bookmark_manager) def bookmark_manager(*args, **kwargs): - with pytest.warns(neo4j.ExperimentalWarning, match="bookmark manager"): - return neo4j.AsyncGraphDatabase.bookmark_manager(*args, **kwargs) + return neo4j.AsyncGraphDatabase.bookmark_manager(*args, **kwargs) @mark_async_test diff --git a/tests/unit/async_/test_driver.py b/tests/unit/async_/test_driver.py index 62848ebbe..ea8026567 100644 --- a/tests/unit/async_/test_driver.py +++ b/tests/unit/async_/test_driver.py @@ -20,7 +20,6 @@ import ssl import typing as t -from contextlib import contextmanager import pytest import typing_extensions as te @@ -63,25 +62,6 @@ ) -@contextmanager -def assert_warns_execute_query_experimental(): - with pytest.warns( - ExperimentalWarning, - match=r"^Driver\.execute_query is experimental\." - ): - yield - - -@contextmanager -def assert_warns_execute_query_bmm_experimental(): - with pytest.warns( - ExperimentalWarning, - match=r"^Driver\.query_bookmark_manager is experimental\." - ): - yield - - - @pytest.mark.parametrize("protocol", ("bolt://", "bolt+s://", "bolt+ssc://")) @pytest.mark.parametrize("host", ("localhost", "127.0.0.1", "[::1]", "[0:0:0:0:0:0:0:1]")) @@ -317,16 +297,14 @@ async def test_get_server_info_parameters_are_experimental( @mark_async_test async def test_with_builtin_bookmark_manager(mocker) -> None: - with pytest.warns(ExperimentalWarning, match="bookmark manager"): - bmm = AsyncGraphDatabase.bookmark_manager() + bmm = AsyncGraphDatabase.bookmark_manager() # could be one line, but want to make sure the type checker assigns # bmm whatever type AsyncGraphDatabase.bookmark_manager() returns session_cls_mock = mocker.patch("neo4j._async.driver.AsyncSession", autospec=True) driver = AsyncGraphDatabase.driver("bolt://localhost") async with driver as driver: - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - _ = driver.session(bookmark_manager=bmm) + _ = driver.session(bookmark_manager=bmm) session_cls_mock.assert_called_once() assert session_cls_mock.call_args[0][1].bookmark_manager is bmm @@ -353,8 +331,7 @@ async def forget(self, databases: t.Iterable[str]) -> None: autospec=True) driver = AsyncGraphDatabase.driver("bolt://localhost") async with driver as driver: - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - _ = driver.session(bookmark_manager=bmm) + _ = driver.session(bookmark_manager=bmm) session_cls_mock.assert_called_once() assert session_cls_mock.call_args[0][1].bookmark_manager is bmm @@ -381,8 +358,7 @@ def forget(self, databases: t.Iterable[str]) -> None: autospec=True) driver = AsyncGraphDatabase.driver("bolt://localhost") async with driver as driver: - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - _ = driver.session(bookmark_manager=bmm) + _ = driver.session(bookmark_manager=bmm) session_cls_mock.assert_called_once() assert session_cls_mock.call_args[0][1].bookmark_manager is bmm @@ -409,8 +385,7 @@ async def forget(self, databases: t.Iterable[str]) -> None: autospec=True) driver = AsyncGraphDatabase.driver("bolt://localhost") async with driver as driver: - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - _ = driver.session(bookmark_manager=bmm) + _ = driver.session(bookmark_manager=bmm) session_cls_mock.assert_called_once() assert session_cls_mock.call_args[0][1].bookmark_manager is bmm @@ -437,8 +412,7 @@ def forget(self, databases: t.Iterable[str]) -> None: autospec=True) driver = AsyncGraphDatabase.driver("bolt://localhost") async with driver as driver: - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - _ = driver.session(bookmark_manager=bmm) + _ = driver.session(bookmark_manager=bmm) session_cls_mock.assert_called_once() assert session_cls_mock.call_args[0][1].bookmark_manager is bmm @@ -662,11 +636,10 @@ async def test_execute_query_query( session_cls_mock = mocker.patch("neo4j._async.driver.AsyncSession", autospec=True) async with driver as driver: - with assert_warns_execute_query_experimental(): - if positional: - res = await driver.execute_query(query) - else: - res = await driver.execute_query(query_=query) + if positional: + res = await driver.execute_query(query) + else: + res = await driver.execute_query(query_=query) session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value @@ -692,16 +665,14 @@ async def test_execute_query_parameters( session_cls_mock = mocker.patch("neo4j._async.driver.AsyncSession", autospec=True) async with driver as driver: - with assert_warns_execute_query_experimental(): - if parameters is Ellipsis: - parameters = None - res = await driver.execute_query("") + if parameters is Ellipsis: + parameters = None + res = await driver.execute_query("") + else: + if positional: + res = await driver.execute_query("", parameters) else: - if positional: - res = await driver.execute_query("", parameters) - else: - res = await driver.execute_query("", - parameters_=parameters) + res = await driver.execute_query("", parameters_=parameters) session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value @@ -725,11 +696,10 @@ async def test_execute_query_keyword_parameters( session_cls_mock = mocker.patch("neo4j._async.driver.AsyncSession", autospec=True) async with driver as driver: - with assert_warns_execute_query_experimental(): - if parameters is None: - res = await driver.execute_query("") - else: - res = await driver.execute_query("", **parameters) + if parameters is None: + res = await driver.execute_query("") + else: + res = await driver.execute_query("", **parameters) session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value @@ -752,8 +722,7 @@ async def test_reserved_query_keyword_parameters( mocker.patch("neo4j._async.driver.AsyncSession", autospec=True) async with driver as driver: with pytest.raises(ValueError) as exc: - with assert_warns_execute_query_experimental(): - await driver.execute_query("", **parameters) + await driver.execute_query("", **parameters) exc.match("reserved") exc.match(", ".join(f"'{k}'" for k in parameters)) @@ -800,15 +769,14 @@ async def test_execute_query_parameter_precedence( session_cls_mock = mocker.patch("neo4j._async.driver.AsyncSession", autospec=True) async with driver as driver: - with assert_warns_execute_query_experimental(): - if params is None: - res = await driver.execute_query("", **kw_params) + if params is None: + res = await driver.execute_query("", **kw_params) + else: + if positional: + res = await driver.execute_query("", params, **kw_params) else: - if positional: - res = await driver.execute_query("", params, **kw_params) - else: - res = await driver.execute_query("", parameters_=params, - **kw_params) + res = await driver.execute_query("", parameters_=params, + **kw_params) session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value @@ -827,8 +795,8 @@ async def test_execute_query_parameter_precedence( (None, "execute_write"), ("r", "execute_read"), ("w", "execute_write"), - (neo4j.RoutingControl.READERS, "execute_read"), - (neo4j.RoutingControl.WRITERS, "execute_write"), + (neo4j.RoutingControl.READ, "execute_read"), + (neo4j.RoutingControl.WRITE, "execute_write"), ) ) @pytest.mark.parametrize("positional", (True, False)) @@ -841,14 +809,13 @@ async def test_execute_query_routing_control( session_cls_mock = mocker.patch("neo4j._async.driver.AsyncSession", autospec=True) async with driver as driver: - with assert_warns_execute_query_experimental(): - if routing_mode is None: - res = await driver.execute_query("") + if routing_mode is None: + res = await driver.execute_query("") + else: + if positional: + res = await driver.execute_query("", None, routing_mode) else: - if positional: - res = await driver.execute_query("", None, routing_mode) - else: - res = await driver.execute_query("", routing_=routing_mode) + res = await driver.execute_query("", routing_=routing_mode) session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value @@ -873,15 +840,14 @@ async def test_execute_query_database( session_cls_mock = mocker.patch("neo4j._async.driver.AsyncSession", autospec=True) async with driver as driver: - with assert_warns_execute_query_experimental(): - if database is Ellipsis: - database = None - await driver.execute_query("") + if database is Ellipsis: + database = None + await driver.execute_query("") + else: + if positional: + await driver.execute_query("", None, "w", database) else: - if positional: - await driver.execute_query("", None, "w", database) - else: - await driver.execute_query("", database_=database) + await driver.execute_query("", database_=database) session_cls_mock.assert_called_once() session_config = session_cls_mock.call_args.args[1] @@ -898,19 +864,18 @@ async def test_execute_query_impersonated_user( session_cls_mock = mocker.patch("neo4j._async.driver.AsyncSession", autospec=True) async with driver as driver: - with assert_warns_execute_query_experimental(): - if impersonated_user is Ellipsis: - impersonated_user = None - await driver.execute_query("") + if impersonated_user is Ellipsis: + impersonated_user = None + await driver.execute_query("") + else: + if positional: + await driver.execute_query( + "", None, "w", None, impersonated_user + ) else: - if positional: - await driver.execute_query( - "", None, "w", None, impersonated_user - ) - else: - await driver.execute_query( - "", impersonated_user_=impersonated_user - ) + await driver.execute_query( + "", impersonated_user_=impersonated_user + ) session_cls_mock.assert_called_once() session_config = session_cls_mock.call_args.args[1] @@ -928,20 +893,18 @@ async def test_execute_query_bookmark_manager( session_cls_mock = mocker.patch("neo4j._async.driver.AsyncSession", autospec=True) async with driver as driver: - with assert_warns_execute_query_experimental(): - if bookmark_manager is Ellipsis: - with assert_warns_execute_query_bmm_experimental(): - bookmark_manager = driver.query_bookmark_manager - await driver.execute_query("") + if bookmark_manager is Ellipsis: + bookmark_manager = driver.execute_query_bookmark_manager + await driver.execute_query("") + else: + if positional: + await driver.execute_query( + "", None, "w", None, None, bookmark_manager + ) else: - if positional: - await driver.execute_query( - "", None, "w", None, None, bookmark_manager - ) - else: - await driver.execute_query( - "", bookmark_manager_=bookmark_manager - ) + await driver.execute_query( + "", bookmark_manager_=bookmark_manager + ) session_cls_mock.assert_called_once() session_config = session_cls_mock.call_args.args[1] @@ -960,25 +923,22 @@ async def test_execute_query_result_transformer( autospec=True) res: t.Any async with driver as driver: - with assert_warns_execute_query_experimental(): - if result_transformer is Ellipsis: - result_transformer = AsyncResult.to_eager_result - res_default: neo4j.EagerResult = await driver.execute_query("") - res = res_default + if result_transformer is Ellipsis: + result_transformer = AsyncResult.to_eager_result + res_default: neo4j.EagerResult = await driver.execute_query("") + res = res_default + else: + res_custom: SomeClass + if positional: + bmm = driver.execute_query_bookmark_manager + res_custom = await driver.execute_query( + "", None, "w", None, None, bmm, None, result_transformer + ) else: - res_custom: SomeClass - if positional: - with assert_warns_execute_query_bmm_experimental(): - bmm = driver.query_bookmark_manager - res_custom = await driver.execute_query( - "", None, "w", None, None, bmm, None, - result_transformer - ) - else: - res_custom = await driver.execute_query( - "", result_transformer_=result_transformer - ) - res = res_custom + res_custom = await driver.execute_query( + "", result_transformer_=result_transformer + ) + res = res_custom session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value diff --git a/tests/unit/async_/work/test_result.py b/tests/unit/async_/work/test_result.py index 7bcdbaebc..47a4a0808 100644 --- a/tests/unit/async_/work/test_result.py +++ b/tests/unit/async_/work/test_result.py @@ -29,7 +29,6 @@ Address, AsyncResult, EagerResult, - ExperimentalWarning, Record, ResultSummary, ServerInfo, @@ -56,15 +55,6 @@ from ...._async_compat import mark_async_test -@contextmanager -def assert_warns_to_eager_result_experimental(): - with pytest.warns( - ExperimentalWarning, - match=r"^Result\.to_eager_result is experimental\." - ): - yield - - class Records: def __init__(self, fields, records): self.fields = tuple(fields) @@ -720,8 +710,7 @@ async def test_to_eager_result(records): connection = AsyncConnectionStub(records=records, summary_meta=summary) result = AsyncResult(connection, 1, noop, noop) await result._run("CYPHER", {}, None, None, "r", None, None, None) - with assert_warns_to_eager_result_experimental(): - eager_result = await result.to_eager_result() + eager_result = await result.to_eager_result() assert isinstance(eager_result, EagerResult) diff --git a/tests/unit/common/test_conf.py b/tests/unit/common/test_conf.py index 6377f74ab..ce8bceb4c 100644 --- a/tests/unit/common/test_conf.py +++ b/tests/unit/common/test_conf.py @@ -21,7 +21,6 @@ import pytest from neo4j import ( - ExperimentalWarning, TrustAll, TrustCustomCAs, TrustSystemCAs, @@ -191,14 +190,6 @@ def test_pool_config_deprecated_and_new_trust_config(value_trust, "trusted_certificates": trusted_certificates}) -@pytest.mark.parametrize("config_cls", (WorkspaceConfig, SessionConfig)) -def test_bookmark_manager_is_experimental(config_cls): - bmm = object() - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - config = config_cls.consume({"bookmark_manager": bmm}) - assert config.bookmark_manager is bmm - - def test_config_consume_chain(): test_config = {} @@ -207,10 +198,9 @@ def test_config_consume_chain(): test_config.update(test_session_config) - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - consumed_pool_config, consumed_session_config = Config.consume_chain( - test_config, PoolConfig, SessionConfig - ) + consumed_pool_config, consumed_session_config = Config.consume_chain( + test_config, PoolConfig, SessionConfig + ) assert isinstance(consumed_pool_config, PoolConfig) assert isinstance(consumed_session_config, SessionConfig) diff --git a/tests/unit/mixed/io/test_direct.py b/tests/unit/mixed/io/test_direct.py index ec1e9bb3e..63fba1e7b 100644 --- a/tests/unit/mixed/io/test_direct.py +++ b/tests/unit/mixed/io/test_direct.py @@ -26,9 +26,7 @@ import pytest -from neo4j._async.io._pool import AcquireAuth as AsyncAcquireAuth from neo4j._deadline import Deadline -from neo4j._sync.io._pool import AcquireAuth from ...async_.io.test_direct import AsyncFakeBoltPool from ...sync.io.test_direct import FakeBoltPool diff --git a/tests/unit/sync/io/test_class_bolt5x1.py b/tests/unit/sync/io/test_class_bolt5x1.py index 9ef06704f..783638a25 100644 --- a/tests/unit/sync/io/test_class_bolt5x1.py +++ b/tests/unit/sync/io/test_class_bolt5x1.py @@ -24,7 +24,6 @@ import neo4j.exceptions from neo4j._conf import PoolConfig from neo4j._sync.io._bolt5 import Bolt5x1 -from neo4j.auth_management import AuthManagers from neo4j.exceptions import ConfigurationError from ...._async_compat import mark_sync_test diff --git a/tests/unit/sync/io/test_class_bolt5x2.py b/tests/unit/sync/io/test_class_bolt5x2.py index 5eb2092c3..79e9cace6 100644 --- a/tests/unit/sync/io/test_class_bolt5x2.py +++ b/tests/unit/sync/io/test_class_bolt5x2.py @@ -24,7 +24,6 @@ import neo4j from neo4j._conf import PoolConfig from neo4j._sync.io._bolt5 import Bolt5x2 -from neo4j.auth_management import AuthManagers from ...._async_compat import mark_sync_test diff --git a/tests/unit/sync/test_bookmark_manager.py b/tests/unit/sync/test_bookmark_manager.py index 8e0133f0c..f560d0038 100644 --- a/tests/unit/sync/test_bookmark_manager.py +++ b/tests/unit/sync/test_bookmark_manager.py @@ -36,8 +36,7 @@ @copy_signature(neo4j.GraphDatabase.bookmark_manager) def bookmark_manager(*args, **kwargs): - with pytest.warns(neo4j.ExperimentalWarning, match="bookmark manager"): - return neo4j.GraphDatabase.bookmark_manager(*args, **kwargs) + return neo4j.GraphDatabase.bookmark_manager(*args, **kwargs) @mark_sync_test diff --git a/tests/unit/sync/test_driver.py b/tests/unit/sync/test_driver.py index 10b7c6e16..7a60f0f98 100644 --- a/tests/unit/sync/test_driver.py +++ b/tests/unit/sync/test_driver.py @@ -20,7 +20,6 @@ import ssl import typing as t -from contextlib import contextmanager import pytest import typing_extensions as te @@ -62,25 +61,6 @@ ) -@contextmanager -def assert_warns_execute_query_experimental(): - with pytest.warns( - ExperimentalWarning, - match=r"^Driver\.execute_query is experimental\." - ): - yield - - -@contextmanager -def assert_warns_execute_query_bmm_experimental(): - with pytest.warns( - ExperimentalWarning, - match=r"^Driver\.query_bookmark_manager is experimental\." - ): - yield - - - @pytest.mark.parametrize("protocol", ("bolt://", "bolt+s://", "bolt+ssc://")) @pytest.mark.parametrize("host", ("localhost", "127.0.0.1", "[::1]", "[0:0:0:0:0:0:0:1]")) @@ -316,16 +296,14 @@ def test_get_server_info_parameters_are_experimental( @mark_sync_test def test_with_builtin_bookmark_manager(mocker) -> None: - with pytest.warns(ExperimentalWarning, match="bookmark manager"): - bmm = GraphDatabase.bookmark_manager() + bmm = GraphDatabase.bookmark_manager() # could be one line, but want to make sure the type checker assigns # bmm whatever type AsyncGraphDatabase.bookmark_manager() returns session_cls_mock = mocker.patch("neo4j._sync.driver.Session", autospec=True) driver = GraphDatabase.driver("bolt://localhost") with driver as driver: - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - _ = driver.session(bookmark_manager=bmm) + _ = driver.session(bookmark_manager=bmm) session_cls_mock.assert_called_once() assert session_cls_mock.call_args[0][1].bookmark_manager is bmm @@ -352,8 +330,7 @@ def forget(self, databases: t.Iterable[str]) -> None: autospec=True) driver = GraphDatabase.driver("bolt://localhost") with driver as driver: - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - _ = driver.session(bookmark_manager=bmm) + _ = driver.session(bookmark_manager=bmm) session_cls_mock.assert_called_once() assert session_cls_mock.call_args[0][1].bookmark_manager is bmm @@ -380,8 +357,7 @@ def forget(self, databases: t.Iterable[str]) -> None: autospec=True) driver = GraphDatabase.driver("bolt://localhost") with driver as driver: - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - _ = driver.session(bookmark_manager=bmm) + _ = driver.session(bookmark_manager=bmm) session_cls_mock.assert_called_once() assert session_cls_mock.call_args[0][1].bookmark_manager is bmm @@ -408,8 +384,7 @@ def forget(self, databases: t.Iterable[str]) -> None: autospec=True) driver = GraphDatabase.driver("bolt://localhost") with driver as driver: - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - _ = driver.session(bookmark_manager=bmm) + _ = driver.session(bookmark_manager=bmm) session_cls_mock.assert_called_once() assert session_cls_mock.call_args[0][1].bookmark_manager is bmm @@ -436,8 +411,7 @@ def forget(self, databases: t.Iterable[str]) -> None: autospec=True) driver = GraphDatabase.driver("bolt://localhost") with driver as driver: - with pytest.warns(ExperimentalWarning, match="bookmark_manager"): - _ = driver.session(bookmark_manager=bmm) + _ = driver.session(bookmark_manager=bmm) session_cls_mock.assert_called_once() assert session_cls_mock.call_args[0][1].bookmark_manager is bmm @@ -661,11 +635,10 @@ def test_execute_query_query( session_cls_mock = mocker.patch("neo4j._sync.driver.Session", autospec=True) with driver as driver: - with assert_warns_execute_query_experimental(): - if positional: - res = driver.execute_query(query) - else: - res = driver.execute_query(query_=query) + if positional: + res = driver.execute_query(query) + else: + res = driver.execute_query(query_=query) session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value @@ -691,16 +664,14 @@ def test_execute_query_parameters( session_cls_mock = mocker.patch("neo4j._sync.driver.Session", autospec=True) with driver as driver: - with assert_warns_execute_query_experimental(): - if parameters is Ellipsis: - parameters = None - res = driver.execute_query("") + if parameters is Ellipsis: + parameters = None + res = driver.execute_query("") + else: + if positional: + res = driver.execute_query("", parameters) else: - if positional: - res = driver.execute_query("", parameters) - else: - res = driver.execute_query("", - parameters_=parameters) + res = driver.execute_query("", parameters_=parameters) session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value @@ -724,11 +695,10 @@ def test_execute_query_keyword_parameters( session_cls_mock = mocker.patch("neo4j._sync.driver.Session", autospec=True) with driver as driver: - with assert_warns_execute_query_experimental(): - if parameters is None: - res = driver.execute_query("") - else: - res = driver.execute_query("", **parameters) + if parameters is None: + res = driver.execute_query("") + else: + res = driver.execute_query("", **parameters) session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value @@ -751,8 +721,7 @@ def test_reserved_query_keyword_parameters( mocker.patch("neo4j._sync.driver.Session", autospec=True) with driver as driver: with pytest.raises(ValueError) as exc: - with assert_warns_execute_query_experimental(): - driver.execute_query("", **parameters) + driver.execute_query("", **parameters) exc.match("reserved") exc.match(", ".join(f"'{k}'" for k in parameters)) @@ -799,15 +768,14 @@ def test_execute_query_parameter_precedence( session_cls_mock = mocker.patch("neo4j._sync.driver.Session", autospec=True) with driver as driver: - with assert_warns_execute_query_experimental(): - if params is None: - res = driver.execute_query("", **kw_params) + if params is None: + res = driver.execute_query("", **kw_params) + else: + if positional: + res = driver.execute_query("", params, **kw_params) else: - if positional: - res = driver.execute_query("", params, **kw_params) - else: - res = driver.execute_query("", parameters_=params, - **kw_params) + res = driver.execute_query("", parameters_=params, + **kw_params) session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value @@ -826,8 +794,8 @@ def test_execute_query_parameter_precedence( (None, "execute_write"), ("r", "execute_read"), ("w", "execute_write"), - (neo4j.RoutingControl.READERS, "execute_read"), - (neo4j.RoutingControl.WRITERS, "execute_write"), + (neo4j.RoutingControl.READ, "execute_read"), + (neo4j.RoutingControl.WRITE, "execute_write"), ) ) @pytest.mark.parametrize("positional", (True, False)) @@ -840,14 +808,13 @@ def test_execute_query_routing_control( session_cls_mock = mocker.patch("neo4j._sync.driver.Session", autospec=True) with driver as driver: - with assert_warns_execute_query_experimental(): - if routing_mode is None: - res = driver.execute_query("") + if routing_mode is None: + res = driver.execute_query("") + else: + if positional: + res = driver.execute_query("", None, routing_mode) else: - if positional: - res = driver.execute_query("", None, routing_mode) - else: - res = driver.execute_query("", routing_=routing_mode) + res = driver.execute_query("", routing_=routing_mode) session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value @@ -872,15 +839,14 @@ def test_execute_query_database( session_cls_mock = mocker.patch("neo4j._sync.driver.Session", autospec=True) with driver as driver: - with assert_warns_execute_query_experimental(): - if database is Ellipsis: - database = None - driver.execute_query("") + if database is Ellipsis: + database = None + driver.execute_query("") + else: + if positional: + driver.execute_query("", None, "w", database) else: - if positional: - driver.execute_query("", None, "w", database) - else: - driver.execute_query("", database_=database) + driver.execute_query("", database_=database) session_cls_mock.assert_called_once() session_config = session_cls_mock.call_args.args[1] @@ -897,19 +863,18 @@ def test_execute_query_impersonated_user( session_cls_mock = mocker.patch("neo4j._sync.driver.Session", autospec=True) with driver as driver: - with assert_warns_execute_query_experimental(): - if impersonated_user is Ellipsis: - impersonated_user = None - driver.execute_query("") + if impersonated_user is Ellipsis: + impersonated_user = None + driver.execute_query("") + else: + if positional: + driver.execute_query( + "", None, "w", None, impersonated_user + ) else: - if positional: - driver.execute_query( - "", None, "w", None, impersonated_user - ) - else: - driver.execute_query( - "", impersonated_user_=impersonated_user - ) + driver.execute_query( + "", impersonated_user_=impersonated_user + ) session_cls_mock.assert_called_once() session_config = session_cls_mock.call_args.args[1] @@ -927,20 +892,18 @@ def test_execute_query_bookmark_manager( session_cls_mock = mocker.patch("neo4j._sync.driver.Session", autospec=True) with driver as driver: - with assert_warns_execute_query_experimental(): - if bookmark_manager is Ellipsis: - with assert_warns_execute_query_bmm_experimental(): - bookmark_manager = driver.query_bookmark_manager - driver.execute_query("") + if bookmark_manager is Ellipsis: + bookmark_manager = driver.execute_query_bookmark_manager + driver.execute_query("") + else: + if positional: + driver.execute_query( + "", None, "w", None, None, bookmark_manager + ) else: - if positional: - driver.execute_query( - "", None, "w", None, None, bookmark_manager - ) - else: - driver.execute_query( - "", bookmark_manager_=bookmark_manager - ) + driver.execute_query( + "", bookmark_manager_=bookmark_manager + ) session_cls_mock.assert_called_once() session_config = session_cls_mock.call_args.args[1] @@ -959,25 +922,22 @@ def test_execute_query_result_transformer( autospec=True) res: t.Any with driver as driver: - with assert_warns_execute_query_experimental(): - if result_transformer is Ellipsis: - result_transformer = Result.to_eager_result - res_default: neo4j.EagerResult = driver.execute_query("") - res = res_default + if result_transformer is Ellipsis: + result_transformer = Result.to_eager_result + res_default: neo4j.EagerResult = driver.execute_query("") + res = res_default + else: + res_custom: SomeClass + if positional: + bmm = driver.execute_query_bookmark_manager + res_custom = driver.execute_query( + "", None, "w", None, None, bmm, None, result_transformer + ) else: - res_custom: SomeClass - if positional: - with assert_warns_execute_query_bmm_experimental(): - bmm = driver.query_bookmark_manager - res_custom = driver.execute_query( - "", None, "w", None, None, bmm, None, - result_transformer - ) - else: - res_custom = driver.execute_query( - "", result_transformer_=result_transformer - ) - res = res_custom + res_custom = driver.execute_query( + "", result_transformer_=result_transformer + ) + res = res_custom session_cls_mock.assert_called_once() session_mock = session_cls_mock.return_value diff --git a/tests/unit/sync/work/test_result.py b/tests/unit/sync/work/test_result.py index 40afcbd78..9899bd875 100644 --- a/tests/unit/sync/work/test_result.py +++ b/tests/unit/sync/work/test_result.py @@ -28,7 +28,6 @@ from neo4j import ( Address, EagerResult, - ExperimentalWarning, Record, Result, ResultSummary, @@ -56,15 +55,6 @@ from ...._async_compat import mark_sync_test -@contextmanager -def assert_warns_to_eager_result_experimental(): - with pytest.warns( - ExperimentalWarning, - match=r"^Result\.to_eager_result is experimental\." - ): - yield - - class Records: def __init__(self, fields, records): self.fields = tuple(fields) @@ -720,8 +710,7 @@ def test_to_eager_result(records): connection = ConnectionStub(records=records, summary_meta=summary) result = Result(connection, 1, noop, noop) result._run("CYPHER", {}, None, None, "r", None, None, None) - with assert_warns_to_eager_result_experimental(): - eager_result = result.to_eager_result() + eager_result = result.to_eager_result() assert isinstance(eager_result, EagerResult)