diff --git a/google/cloud/bigquery/__init__.py b/google/cloud/bigquery/__init__.py index caf81d9aa..e80907ec9 100644 --- a/google/cloud/bigquery/__init__.py +++ b/google/cloud/bigquery/__init__.py @@ -27,6 +27,7 @@ - :class:`~google.cloud.bigquery.table.Table` represents a single "relation". """ +import warnings from google.cloud.bigquery import version as bigquery_version @@ -114,6 +115,11 @@ from google.cloud.bigquery.table import TimePartitioning from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration +try: + import bigquery_magics # type: ignore +except ImportError: + bigquery_magics = None + __all__ = [ "__version__", "Client", @@ -214,8 +220,16 @@ def load_ipython_extension(ipython): """Called by IPython when this module is loaded as an IPython extension.""" - from google.cloud.bigquery.magics.magics import _cell_magic - - ipython.register_magic_function( - _cell_magic, magic_kind="cell", magic_name="bigquery" + warnings.warn( + "%load_ext google.cloud.bigquery is deprecated. Install bigquery-magics package and use `%load_ext bigquery_magics`, instead.", + category=FutureWarning, ) + + if bigquery_magics is not None: + bigquery_magics.load_ipython_extension(ipython) + else: + from google.cloud.bigquery.magics.magics import _cell_magic + + ipython.register_magic_function( + _cell_magic, magic_kind="cell", magic_name="bigquery" + ) diff --git a/google/cloud/bigquery/magics/magics.py b/google/cloud/bigquery/magics/magics.py index 6e6b21965..b153d959a 100644 --- a/google/cloud/bigquery/magics/magics.py +++ b/google/cloud/bigquery/magics/magics.py @@ -14,70 +14,11 @@ """IPython Magics -.. function:: %%bigquery - - IPython cell magic to run a query and display the result as a DataFrame - - .. code-block:: python - - %%bigquery [] [--project ] [--use_legacy_sql] - [--verbose] [--params ] - - - Parameters: - - * ```` (Optional[line argument]): - variable to store the query results. The results are not displayed if - this parameter is used. If an error occurs during the query execution, - the corresponding ``QueryJob`` instance (if available) is stored in - the variable instead. - * ``--destination_table`` (Optional[line argument]): - A dataset and table to store the query results. If table does not exists, - it will be created. If table already exists, its data will be overwritten. - Variable should be in a format .. - * ``--no_query_cache`` (Optional[line argument]): - Do not use cached query results. - * ``--project `` (Optional[line argument]): - Project to use for running the query. Defaults to the context - :attr:`~google.cloud.bigquery.magics.Context.project`. - * ``--use_bqstorage_api`` (Optional[line argument]): - [Deprecated] Not used anymore, as BigQuery Storage API is used by default. - * ``--use_rest_api`` (Optional[line argument]): - Use the BigQuery REST API instead of the Storage API. - * ``--use_legacy_sql`` (Optional[line argument]): - Runs the query using Legacy SQL syntax. Defaults to Standard SQL if - this argument not used. - * ``--verbose`` (Optional[line argument]): - If this flag is used, information including the query job ID and the - amount of time for the query to complete will not be cleared after the - query is finished. By default, this information will be displayed but - will be cleared after the query is finished. - * ``--params `` (Optional[line argument]): - If present, the argument following the ``--params`` flag must be - either: - - * :class:`str` - A JSON string representation of a dictionary in the - format ``{"param_name": "param_value"}`` (ex. ``{"num": 17}``). Use - of the parameter in the query should be indicated with - ``@param_name``. See ``In[5]`` in the Examples section below. - - * :class:`dict` reference - A reference to a ``dict`` in the format - ``{"param_name": "param_value"}``, where the value types must be JSON - serializable. The variable reference is indicated by a ``$`` before - the variable name (ex. ``$my_dict_var``). See ``In[6]`` and ``In[7]`` - in the Examples section below. - - * ```` (required, cell argument): - SQL query to run. If the query does not contain any whitespace (aside - from leading and trailing whitespace), it is assumed to represent a - fully-qualified table ID, and the latter's data will be fetched. +Install ``bigquery-magics`` and call ``%load_ext bigquery_magics`` to use the +``%%bigquery`` cell magic. - Returns: - A :class:`pandas.DataFrame` with the query results. - - .. note:: - All queries run using this magic will run using the context - :attr:`~google.cloud.bigquery.magics.Context.credentials`. +See the `BigQuery Magics reference documentation +`_. """ from __future__ import print_function @@ -109,6 +50,11 @@ from google.cloud.bigquery.dbapi import _helpers from google.cloud.bigquery.magics import line_arg_parser as lap +try: + import bigquery_magics # type: ignore +except ImportError: + bigquery_magics = None + IPYTHON_USER_AGENT = "ipython-{}".format(IPython.__version__) @@ -280,7 +226,14 @@ def progress_bar_type(self, value): self._progress_bar_type = value -context = Context() +# If bigquery_magics is available, we load that extension rather than this one. +# Ensure google.cloud.bigquery.magics.context setters are on the correct magics +# implementation in case the user has installed the package but hasn't updated +# their code. +if bigquery_magics is not None: + context = bigquery_magics.context +else: + context = Context() def _handle_error(error, destination_var=None): diff --git a/samples/magics/noxfile_config.py b/samples/magics/noxfile_config.py new file mode 100644 index 000000000..982751b8b --- /dev/null +++ b/samples/magics/noxfile_config.py @@ -0,0 +1,37 @@ +# Copyright 2020 Google LLC +# +# 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +# You can copy this file into your directory, then it will be inported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [ + "2.7", + ], + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # "gcloud_project_env": "BUILD_SPECIFIC_GCLOUD_PROJECT", + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} diff --git a/samples/magics/query.py b/samples/magics/query.py index 4d3b4418b..0ac947db0 100644 --- a/samples/magics/query.py +++ b/samples/magics/query.py @@ -24,7 +24,7 @@ def query() -> "pandas.DataFrame": ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + ip.extension_manager.load_extension("bigquery_magics") sample = """ # [START bigquery_jupyter_query] diff --git a/samples/magics/query_params_scalars.py b/samples/magics/query_params_scalars.py index e833ef93b..74f665acb 100644 --- a/samples/magics/query_params_scalars.py +++ b/samples/magics/query_params_scalars.py @@ -24,7 +24,7 @@ def query_with_parameters() -> "pandas.DataFrame": ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + ip.extension_manager.load_extension("bigquery_magics") sample = """ # [START bigquery_jupyter_query_params_scalars] diff --git a/samples/magics/requirements.txt b/samples/magics/requirements.txt index a5b4e2aaa..a1044c231 100644 --- a/samples/magics/requirements.txt +++ b/samples/magics/requirements.txt @@ -1,3 +1,4 @@ +bigquery_magics==0.1.0 db-dtypes==1.2.0 google.cloud.bigquery==3.25.0 google-cloud-bigquery-storage==2.25.0 diff --git a/samples/notebooks/jupyter_tutorial_test.py b/samples/notebooks/jupyter_tutorial_test.py index 9d42a4eda..2c2cf9390 100644 --- a/samples/notebooks/jupyter_tutorial_test.py +++ b/samples/notebooks/jupyter_tutorial_test.py @@ -60,7 +60,7 @@ def _strip_region_tags(sample_text: str) -> str: def test_jupyter_tutorial(ipython: "TerminalInteractiveShell") -> None: matplotlib.use("agg") ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + ip.extension_manager.load_extension("bigquery_magics") sample = """ # [START bigquery_jupyter_magic_gender_by_year] diff --git a/samples/notebooks/requirements.txt b/samples/notebooks/requirements.txt index 78945d28b..3896a2aec 100644 --- a/samples/notebooks/requirements.txt +++ b/samples/notebooks/requirements.txt @@ -1,3 +1,4 @@ +bigquery-magics==0.1.0 db-dtypes==1.2.0 google-cloud-bigquery==3.25.0 google-cloud-bigquery-storage==2.25.0 diff --git a/setup.py b/setup.py index db8e06113..9641fe695 100644 --- a/setup.py +++ b/setup.py @@ -66,8 +66,7 @@ ], "geopandas": ["geopandas>=0.9.0, <1.0dev", "Shapely>=1.8.4, <3.0.0dev"], "ipython": [ - "ipython>=7.23.1,!=8.1.0", - "ipykernel>=6.0.0", + "bigquery-magics >= 0.1.0", ], "tqdm": ["tqdm >= 4.7.4, <5.0.0dev"], "opentelemetry": [ diff --git a/testing/constraints-3.7.txt b/testing/constraints-3.7.txt index c09978d5d..fda7ce951 100644 --- a/testing/constraints-3.7.txt +++ b/testing/constraints-3.7.txt @@ -5,6 +5,7 @@ # # e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", # Then this file should have foo==1.14.0 +bigquery-magics==0.1.0 db-dtypes==0.3.0 geopandas==0.9.0 google-api-core==2.11.1 diff --git a/tests/system/test_magics.py b/tests/system/test_magics.py index 3d761cd35..72d358a74 100644 --- a/tests/system/test_magics.py +++ b/tests/system/test_magics.py @@ -50,7 +50,10 @@ def test_bigquery_magic(ipython_interactive): current_process = psutil.Process() conn_count_start = len(current_process.connections()) - ip.extension_manager.load_extension("google.cloud.bigquery") + # Deprecated, but should still work in google-cloud-bigquery 3.x. + with pytest.warns(FutureWarning, match="bigquery_magics"): + ip.extension_manager.load_extension("google.cloud.bigquery") + sql = """ SELECT CONCAT( diff --git a/tests/unit/test_magics.py b/tests/unit/test_magics.py index 4b1aaf14d..73b29df6b 100644 --- a/tests/unit/test_magics.py +++ b/tests/unit/test_magics.py @@ -155,9 +155,10 @@ def test_context_with_default_credentials(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_context_with_default_connection(): +def test_context_with_default_connection(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._credentials = None magics.context._project = None magics.context._connection = None @@ -218,9 +219,10 @@ def test_context_credentials_and_project_can_be_set_explicitly(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_context_with_custom_connection(): +def test_context_with_custom_connection(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None magics.context._credentials = None context_conn = magics.context._connection = make_connection( @@ -439,11 +441,9 @@ def test__create_dataset_if_necessary_not_exist(): @pytest.mark.usefixtures("ipython_interactive") def test_extension_load(): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") - # verify that the magic is registered and has the correct source - magic = ip.magics_manager.magics["cell"].get("bigquery") - assert magic.__module__ == "google.cloud.bigquery.magics.magics" + with pytest.warns(FutureWarning, match="bigquery_magics"): + bigquery.load_ipython_extension(ip) @pytest.mark.usefixtures("ipython_interactive") @@ -453,7 +453,8 @@ def test_extension_load(): ) def test_bigquery_magic_without_optional_arguments(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) mock_credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -494,9 +495,10 @@ def test_bigquery_magic_without_optional_arguments(monkeypatch): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_default_connection_user_agent(): +def test_bigquery_magic_default_connection_user_agent(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._connection = None credentials_mock = mock.create_autospec( @@ -519,9 +521,10 @@ def test_bigquery_magic_default_connection_user_agent(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_with_legacy_sql(): +def test_bigquery_magic_with_legacy_sql(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -538,9 +541,10 @@ def test_bigquery_magic_with_legacy_sql(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_result_saved_to_variable(ipython_ns_cleanup): +def test_bigquery_magic_with_result_saved_to_variable(ipython_ns_cleanup, monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -571,9 +575,10 @@ def test_bigquery_magic_with_result_saved_to_variable(ipython_ns_cleanup): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_does_not_clear_display_in_verbose_mode(): +def test_bigquery_magic_does_not_clear_display_in_verbose_mode(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -592,9 +597,10 @@ def test_bigquery_magic_does_not_clear_display_in_verbose_mode(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_clears_display_in_non_verbose_mode(): +def test_bigquery_magic_clears_display_in_non_verbose_mode(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -618,7 +624,8 @@ def test_bigquery_magic_clears_display_in_non_verbose_mode(): ) def test_bigquery_magic_with_bqstorage_from_argument(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) mock_credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -686,7 +693,8 @@ def test_bigquery_magic_with_rest_client_requested(monkeypatch): pandas = pytest.importorskip("pandas") ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) mock_credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -726,9 +734,10 @@ def test_bigquery_magic_with_rest_client_requested(monkeypatch): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_w_max_results_invalid(): +def test_bigquery_magic_w_max_results_invalid(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None credentials_mock = mock.create_autospec( @@ -748,9 +757,10 @@ def test_bigquery_magic_w_max_results_invalid(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_w_max_results_valid_calls_queryjob_result(): +def test_bigquery_magic_w_max_results_valid_calls_queryjob_result(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None credentials_mock = mock.create_autospec( @@ -782,9 +792,10 @@ def test_bigquery_magic_w_max_results_valid_calls_queryjob_result(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_w_max_results_query_job_results_fails(): +def test_bigquery_magic_w_max_results_query_job_results_fails(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None credentials_mock = mock.create_autospec( @@ -819,9 +830,10 @@ def test_bigquery_magic_w_max_results_query_job_results_fails(): assert close_transports.called -def test_bigquery_magic_w_table_id_invalid(): +def test_bigquery_magic_w_table_id_invalid(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None credentials_mock = mock.create_autospec( @@ -848,9 +860,10 @@ def test_bigquery_magic_w_table_id_invalid(): assert "Traceback (most recent call last)" not in output -def test_bigquery_magic_w_missing_query(): +def test_bigquery_magic_w_missing_query(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None credentials_mock = mock.create_autospec( @@ -873,9 +886,10 @@ def test_bigquery_magic_w_missing_query(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_w_table_id_and_destination_var(ipython_ns_cleanup): +def test_bigquery_magic_w_table_id_and_destination_var(ipython_ns_cleanup, monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None ipython_ns_cleanup.append((ip, "df")) @@ -915,9 +929,10 @@ def test_bigquery_magic_w_table_id_and_destination_var(ipython_ns_cleanup): bigquery_storage is None, reason="Requires `google-cloud-bigquery-storage`" ) @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_w_table_id_and_bqstorage_client(): +def test_bigquery_magic_w_table_id_and_bqstorage_client(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None credentials_mock = mock.create_autospec( @@ -959,9 +974,10 @@ def test_bigquery_magic_w_table_id_and_bqstorage_client(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_dryrun_option_sets_job_config(): +def test_bigquery_magic_dryrun_option_sets_job_config(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -980,9 +996,10 @@ def test_bigquery_magic_dryrun_option_sets_job_config(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_dryrun_option_returns_query_job(): +def test_bigquery_magic_dryrun_option_returns_query_job(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1004,9 +1021,12 @@ def test_bigquery_magic_dryrun_option_returns_query_job(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_dryrun_option_variable_error_message(ipython_ns_cleanup): +def test_bigquery_magic_dryrun_option_variable_error_message( + ipython_ns_cleanup, monkeypatch +): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1031,9 +1051,12 @@ def test_bigquery_magic_dryrun_option_variable_error_message(ipython_ns_cleanup) @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_dryrun_option_saves_query_job_to_variable(ipython_ns_cleanup): +def test_bigquery_magic_dryrun_option_saves_query_job_to_variable( + ipython_ns_cleanup, monkeypatch +): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1061,9 +1084,12 @@ def test_bigquery_magic_dryrun_option_saves_query_job_to_variable(ipython_ns_cle @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_saves_query_job_to_variable_on_error(ipython_ns_cleanup): +def test_bigquery_magic_saves_query_job_to_variable_on_error( + ipython_ns_cleanup, monkeypatch +): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1094,9 +1120,10 @@ def test_bigquery_magic_saves_query_job_to_variable_on_error(ipython_ns_cleanup) @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_w_maximum_bytes_billed_invalid(): +def test_bigquery_magic_w_maximum_bytes_billed_invalid(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None credentials_mock = mock.create_autospec( @@ -1118,9 +1145,12 @@ def test_bigquery_magic_w_maximum_bytes_billed_invalid(): ) @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_w_maximum_bytes_billed_overrides_context(param_value, expected): +def test_bigquery_magic_w_maximum_bytes_billed_overrides_context( + param_value, expected, monkeypatch +): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None # Set the default maximum bytes billed, so we know it's overridable by the param. @@ -1158,9 +1188,10 @@ def test_bigquery_magic_w_maximum_bytes_billed_overrides_context(param_value, ex @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_w_maximum_bytes_billed_w_context_inplace(): +def test_bigquery_magic_w_maximum_bytes_billed_w_context_inplace(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None magics.context.default_query_job_config.maximum_bytes_billed = 1337 @@ -1195,9 +1226,10 @@ def test_bigquery_magic_w_maximum_bytes_billed_w_context_inplace(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_w_maximum_bytes_billed_w_context_setter(): +def test_bigquery_magic_w_maximum_bytes_billed_w_context_setter(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None magics.context.default_query_job_config = job.QueryJobConfig( @@ -1236,7 +1268,8 @@ def test_bigquery_magic_w_maximum_bytes_billed_w_context_setter(): @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") def test_bigquery_magic_with_no_query_cache(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) conn = make_connection() monkeypatch.setattr(magics.context, "_connection", conn) monkeypatch.setattr(magics.context, "project", "project-from-context") @@ -1266,7 +1299,8 @@ def test_bigquery_magic_with_no_query_cache(monkeypatch): @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") def test_context_with_no_query_cache_from_context(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) conn = make_connection() monkeypatch.setattr(magics.context, "_connection", conn) monkeypatch.setattr(magics.context, "project", "project-from-context") @@ -1294,7 +1328,8 @@ def test_context_with_no_query_cache_from_context(monkeypatch): @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") def test_bigquery_magic_w_progress_bar_type_w_context_setter(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None magics.context.progress_bar_type = "tqdm_gui" @@ -1338,9 +1373,10 @@ def test_bigquery_magic_w_progress_bar_type_w_context_setter(monkeypatch): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_with_progress_bar_type(): +def test_bigquery_magic_with_progress_bar_type(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.progress_bar_type = None run_query_patch = mock.patch( @@ -1358,9 +1394,10 @@ def test_bigquery_magic_with_progress_bar_type(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_with_project(): +def test_bigquery_magic_with_project(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None credentials_mock = mock.create_autospec( @@ -1382,9 +1419,10 @@ def test_bigquery_magic_with_project(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_with_bigquery_api_endpoint(ipython_ns_cleanup): +def test_bigquery_magic_with_bigquery_api_endpoint(ipython_ns_cleanup, monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._connection = None run_query_patch = mock.patch( @@ -1404,9 +1442,10 @@ def test_bigquery_magic_with_bigquery_api_endpoint(ipython_ns_cleanup): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_with_bigquery_api_endpoint_context_dict(): +def test_bigquery_magic_with_bigquery_api_endpoint_context_dict(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._connection = None magics.context.bigquery_client_options = {} @@ -1427,9 +1466,10 @@ def test_bigquery_magic_with_bigquery_api_endpoint_context_dict(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_with_bqstorage_api_endpoint(ipython_ns_cleanup): +def test_bigquery_magic_with_bqstorage_api_endpoint(ipython_ns_cleanup, monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._connection = None run_query_patch = mock.patch( @@ -1449,9 +1489,10 @@ def test_bigquery_magic_with_bqstorage_api_endpoint(ipython_ns_cleanup): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_with_bqstorage_api_endpoint_context_dict(): +def test_bigquery_magic_with_bqstorage_api_endpoint_context_dict(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._connection = None magics.context.bqstorage_client_options = {} @@ -1472,9 +1513,10 @@ def test_bigquery_magic_with_bqstorage_api_endpoint_context_dict(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_with_multiple_options(): +def test_bigquery_magic_with_multiple_options(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None credentials_mock = mock.create_autospec( @@ -1504,9 +1546,10 @@ def test_bigquery_magic_with_multiple_options(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_string_params(ipython_ns_cleanup): +def test_bigquery_magic_with_string_params(ipython_ns_cleanup, monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1541,9 +1584,10 @@ def test_bigquery_magic_with_string_params(ipython_ns_cleanup): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_dict_params(ipython_ns_cleanup): +def test_bigquery_magic_with_dict_params(ipython_ns_cleanup, monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1585,9 +1629,10 @@ def test_bigquery_magic_with_dict_params(ipython_ns_cleanup): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_dict_params_nonexisting(): +def test_bigquery_magic_with_dict_params_nonexisting(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1600,9 +1645,10 @@ def test_bigquery_magic_with_dict_params_nonexisting(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_dict_params_incorrect_syntax(): +def test_bigquery_magic_with_dict_params_incorrect_syntax(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1616,9 +1662,10 @@ def test_bigquery_magic_with_dict_params_incorrect_syntax(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_dict_params_duplicate(): +def test_bigquery_magic_with_dict_params_duplicate(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1634,9 +1681,10 @@ def test_bigquery_magic_with_dict_params_duplicate(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_option_value_incorrect(): +def test_bigquery_magic_with_option_value_incorrect(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1650,9 +1698,12 @@ def test_bigquery_magic_with_option_value_incorrect(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_dict_params_negative_value(ipython_ns_cleanup): +def test_bigquery_magic_with_dict_params_negative_value( + ipython_ns_cleanup, monkeypatch +): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1690,9 +1741,10 @@ def test_bigquery_magic_with_dict_params_negative_value(ipython_ns_cleanup): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_dict_params_array_value(ipython_ns_cleanup): +def test_bigquery_magic_with_dict_params_array_value(ipython_ns_cleanup, monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1730,9 +1782,10 @@ def test_bigquery_magic_with_dict_params_array_value(ipython_ns_cleanup): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_dict_params_tuple_value(ipython_ns_cleanup): +def test_bigquery_magic_with_dict_params_tuple_value(ipython_ns_cleanup, monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1770,9 +1823,10 @@ def test_bigquery_magic_with_dict_params_tuple_value(ipython_ns_cleanup): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_improperly_formatted_params(): +def test_bigquery_magic_with_improperly_formatted_params(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1788,9 +1842,12 @@ def test_bigquery_magic_with_improperly_formatted_params(): ) @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_valid_query_in_existing_variable(ipython_ns_cleanup, raw_sql): +def test_bigquery_magic_valid_query_in_existing_variable( + ipython_ns_cleanup, raw_sql, monkeypatch +): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1827,9 +1884,10 @@ def test_bigquery_magic_valid_query_in_existing_variable(ipython_ns_cleanup, raw @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_nonexisting_query_variable(): +def test_bigquery_magic_nonexisting_query_variable(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1851,9 +1909,10 @@ def test_bigquery_magic_nonexisting_query_variable(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_empty_query_variable_name(): +def test_bigquery_magic_empty_query_variable_name(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1873,9 +1932,10 @@ def test_bigquery_magic_empty_query_variable_name(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_query_variable_non_string(ipython_ns_cleanup): +def test_bigquery_magic_query_variable_non_string(ipython_ns_cleanup, monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1899,9 +1959,10 @@ def test_bigquery_magic_query_variable_non_string(ipython_ns_cleanup): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_query_variable_not_identifier(): +def test_bigquery_magic_query_variable_not_identifier(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1922,9 +1983,10 @@ def test_bigquery_magic_query_variable_not_identifier(): @pytest.mark.usefixtures("ipython_interactive") @pytest.mark.skipif(pandas is None, reason="Requires `pandas`") -def test_bigquery_magic_with_invalid_multiple_option_values(): +def test_bigquery_magic_with_invalid_multiple_option_values(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -1939,9 +2001,10 @@ def test_bigquery_magic_with_invalid_multiple_option_values(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_omits_tracebacks_from_error_message(): +def test_bigquery_magic_omits_tracebacks_from_error_message(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) credentials_mock = mock.create_autospec( google.auth.credentials.Credentials, instance=True @@ -1966,9 +2029,10 @@ def test_bigquery_magic_omits_tracebacks_from_error_message(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_w_destination_table_invalid_format(): +def test_bigquery_magic_w_destination_table_invalid_format(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context._project = None credentials_mock = mock.create_autospec( @@ -1994,9 +2058,10 @@ def test_bigquery_magic_w_destination_table_invalid_format(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_w_destination_table(): +def test_bigquery_magic_w_destination_table(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -2026,9 +2091,10 @@ def test_bigquery_magic_w_destination_table(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_create_dataset_fails(): +def test_bigquery_magic_create_dataset_fails(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True ) @@ -2056,9 +2122,10 @@ def test_bigquery_magic_create_dataset_fails(): @pytest.mark.usefixtures("ipython_interactive") -def test_bigquery_magic_with_location(): +def test_bigquery_magic_with_location(monkeypatch): ip = IPython.get_ipython() - ip.extension_manager.load_extension("google.cloud.bigquery") + monkeypatch.setattr(bigquery, "bigquery_magics", None) + bigquery.load_ipython_extension(ip) magics.context.credentials = mock.create_autospec( google.auth.credentials.Credentials, instance=True )