From 2e8d0be8cdd1433faeaebf3f6090721f48cbc76f Mon Sep 17 00:00:00 2001 From: Tim Swast Date: Thu, 5 Apr 2018 17:11:48 -0700 Subject: [PATCH 1/2] BUG: only show verbose warning for new pandas versions. --- docs/source/changelog.rst | 6 ++++++ pandas_gbq/gbq.py | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 30281c3d..ffa62f1a 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -1,6 +1,12 @@ Changelog ========= +0.4.1 / 2018-04-05 +------------------ + +- Only show ``verbose`` deprecation warning if Pandas version does not + populate it. (:issue:`157`) + 0.4.0 / 2018-04-03 ------------------ diff --git a/pandas_gbq/gbq.py b/pandas_gbq/gbq.py index cca6d211..e3f78175 100644 --- a/pandas_gbq/gbq.py +++ b/pandas_gbq/gbq.py @@ -14,10 +14,11 @@ BIGQUERY_INSTALLED_VERSION = None +PANDAS_HAS_DEPRECATED_VERBOSITY = False def _check_google_client_version(): - global BIGQUERY_INSTALLED_VERSION + global BIGQUERY_INSTALLED_VERSION, PANDAS_HAS_DEPRECATED_VERBOSITY try: import pkg_resources @@ -36,6 +37,14 @@ def _check_google_client_version(): 'current version {1}'.format( bigquery_minimum_version, BIGQUERY_INSTALLED_VERSION)) + # Add check for Pandas version before showing deprecation warning. + # https://github.com/pydata/pandas-gbq/issues/157 + pandas_installed_version = pkg_resources.get_distribution( + 'pandas').parsed_version + pandas_version_wo_verbosity = pkg_resources.parse_version('0.23.0') + PANDAS_HAS_DEPRECATED_VERBOSITY = ( + pandas_installed_version >= pandas_version_wo_verbosity) + def _test_google_api_imports(): @@ -791,14 +800,15 @@ def read_gbq(query, project_id=None, index_col=None, col_order=None, DataFrame representing results of query """ - if verbose is not None: + + _test_google_api_imports() + + if verbose is not None and PANDAS_HAS_DEPRECATED_VERBOSITY: warnings.warn( "verbose is deprecated and will be removed in " "a future version. Set logging level in order to vary " "verbosity", FutureWarning, stacklevel=1) - _test_google_api_imports() - if not project_id: raise TypeError("Missing required parameter: project_id") @@ -920,7 +930,7 @@ def to_gbq(dataframe, destination_table, project_id, chunksize=None, _test_google_api_imports() - if verbose is not None: + if verbose is not None and PANDAS_HAS_DEPRECATED_VERBOSITY: warnings.warn( "verbose is deprecated and will be removed in " "a future version. Set logging level in order to vary " From 31476bbb67bff61274222b00089680b977e20017 Mon Sep 17 00:00:00 2001 From: Tim Swast Date: Fri, 6 Apr 2018 11:27:34 -0700 Subject: [PATCH 2/2] TST: add unit tests for verbose deprecation warning --- pandas_gbq/gbq.py | 10 +-- pandas_gbq/tests/test_gbq.py | 147 ++++++++++++++++++++++++++++++++++- 2 files changed, 151 insertions(+), 6 deletions(-) diff --git a/pandas_gbq/gbq.py b/pandas_gbq/gbq.py index e3f78175..f8bbaf22 100644 --- a/pandas_gbq/gbq.py +++ b/pandas_gbq/gbq.py @@ -14,11 +14,11 @@ BIGQUERY_INSTALLED_VERSION = None -PANDAS_HAS_DEPRECATED_VERBOSITY = False +SHOW_VERBOSE_DEPRECATION = False def _check_google_client_version(): - global BIGQUERY_INSTALLED_VERSION, PANDAS_HAS_DEPRECATED_VERBOSITY + global BIGQUERY_INSTALLED_VERSION, SHOW_VERBOSE_DEPRECATION try: import pkg_resources @@ -42,7 +42,7 @@ def _check_google_client_version(): pandas_installed_version = pkg_resources.get_distribution( 'pandas').parsed_version pandas_version_wo_verbosity = pkg_resources.parse_version('0.23.0') - PANDAS_HAS_DEPRECATED_VERBOSITY = ( + SHOW_VERBOSE_DEPRECATION = ( pandas_installed_version >= pandas_version_wo_verbosity) @@ -803,7 +803,7 @@ def read_gbq(query, project_id=None, index_col=None, col_order=None, _test_google_api_imports() - if verbose is not None and PANDAS_HAS_DEPRECATED_VERBOSITY: + if verbose is not None and SHOW_VERBOSE_DEPRECATION: warnings.warn( "verbose is deprecated and will be removed in " "a future version. Set logging level in order to vary " @@ -930,7 +930,7 @@ def to_gbq(dataframe, destination_table, project_id, chunksize=None, _test_google_api_imports() - if verbose is not None and PANDAS_HAS_DEPRECATED_VERBOSITY: + if verbose is not None and SHOW_VERBOSE_DEPRECATION: warnings.warn( "verbose is deprecated and will be removed in " "a future version. Set logging level in order to vary " diff --git a/pandas_gbq/tests/test_gbq.py b/pandas_gbq/tests/test_gbq.py index abb670ef..93c48b0c 100644 --- a/pandas_gbq/tests/test_gbq.py +++ b/pandas_gbq/tests/test_gbq.py @@ -282,8 +282,40 @@ def test_get_user_account_credentials_returns_credentials(self): class TestGBQUnit(object): - def test_should_return_credentials_path_set_by_env_var(self): + @pytest.fixture(autouse=True) + def mock_bigquery_client(self, monkeypatch): + import google.cloud.bigquery + import google.cloud.bigquery.table + mock_client = mock.create_autospec(google.cloud.bigquery.Client) + # Mock out SELECT 1 query results. + mock_query = mock.create_autospec(google.cloud.bigquery.QueryJob) + mock_query.state = 'DONE' + mock_rows = mock.create_autospec( + google.cloud.bigquery.table.RowIterator) + mock_rows.total_rows = 1 + mock_rows.schema = [ + google.cloud.bigquery.SchemaField('_f0', 'INTEGER')] + mock_rows.__iter__.return_value = [(1,)] + mock_query.result.return_value = mock_rows + mock_client.query.return_value = mock_query + monkeypatch.setattr( + gbq.GbqConnector, 'get_client', lambda _: mock_client) + + @pytest.fixture(autouse=True) + def no_auth(self, monkeypatch): + import google.auth.credentials + mock_credentials = mock.create_autospec( + google.auth.credentials.Credentials) + monkeypatch.setattr( + gbq.GbqConnector, + 'get_application_default_credentials', + lambda _: mock_credentials) + monkeypatch.setattr( + gbq.GbqConnector, + 'get_user_account_credentials', + lambda _: mock_credentials) + def test_should_return_credentials_path_set_by_env_var(self): env = {'PANDAS_GBQ_CREDENTIALS_FILE': '/tmp/dummy.dat'} with mock.patch.dict('os.environ', env): assert gbq._get_credentials_file() == '/tmp/dummy.dat' @@ -314,6 +346,75 @@ def test_to_gbq_with_no_project_id_given_should_fail(self): with pytest.raises(TypeError): gbq.to_gbq(DataFrame(), 'dataset.tablename') + def test_to_gbq_with_verbose_new_pandas_warns_deprecation(self): + import pkg_resources + min_bq_version = pkg_resources.parse_version('0.29.0') + pandas_version = pkg_resources.parse_version('0.23.0') + with pytest.warns(FutureWarning), \ + mock.patch( + 'pkg_resources.Distribution.parsed_version', + new_callable=mock.PropertyMock) as mock_version: + mock_version.side_effect = [min_bq_version, pandas_version] + try: + gbq.to_gbq( + DataFrame(), + 'dataset.tablename', + project_id='my-project', + verbose=True) + except gbq.TableCreationError: + pass + + def test_to_gbq_with_not_verbose_new_pandas_warns_deprecation(self): + import pkg_resources + min_bq_version = pkg_resources.parse_version('0.29.0') + pandas_version = pkg_resources.parse_version('0.23.0') + with pytest.warns(FutureWarning), \ + mock.patch( + 'pkg_resources.Distribution.parsed_version', + new_callable=mock.PropertyMock) as mock_version: + mock_version.side_effect = [min_bq_version, pandas_version] + try: + gbq.to_gbq( + DataFrame(), + 'dataset.tablename', + project_id='my-project', + verbose=False) + except gbq.TableCreationError: + pass + + def test_to_gbq_wo_verbose_w_new_pandas_no_warnings(self, recwarn): + import pkg_resources + min_bq_version = pkg_resources.parse_version('0.29.0') + pandas_version = pkg_resources.parse_version('0.23.0') + with mock.patch( + 'pkg_resources.Distribution.parsed_version', + new_callable=mock.PropertyMock) as mock_version: + mock_version.side_effect = [min_bq_version, pandas_version] + try: + gbq.to_gbq( + DataFrame(), 'dataset.tablename', project_id='my-project') + except gbq.TableCreationError: + pass + assert len(recwarn) == 0 + + def test_to_gbq_with_verbose_old_pandas_no_warnings(self, recwarn): + import pkg_resources + min_bq_version = pkg_resources.parse_version('0.29.0') + pandas_version = pkg_resources.parse_version('0.22.0') + with mock.patch( + 'pkg_resources.Distribution.parsed_version', + new_callable=mock.PropertyMock) as mock_version: + mock_version.side_effect = [min_bq_version, pandas_version] + try: + gbq.to_gbq( + DataFrame(), + 'dataset.tablename', + project_id='my-project', + verbose=True) + except gbq.TableCreationError: + pass + assert len(recwarn) == 0 + def test_read_gbq_with_no_project_id_given_should_fail(self): with pytest.raises(TypeError): gbq.read_gbq('SELECT 1') @@ -359,6 +460,50 @@ def test_read_gbq_with_corrupted_private_key_json_should_fail(self): 'SELECT 1', project_id='x', private_key=re.sub('[a-z]', '9', _get_private_key_contents())) + def test_read_gbq_with_verbose_new_pandas_warns_deprecation(self): + import pkg_resources + min_bq_version = pkg_resources.parse_version('0.29.0') + pandas_version = pkg_resources.parse_version('0.23.0') + with pytest.warns(FutureWarning), \ + mock.patch( + 'pkg_resources.Distribution.parsed_version', + new_callable=mock.PropertyMock) as mock_version: + mock_version.side_effect = [min_bq_version, pandas_version] + gbq.read_gbq('SELECT 1', project_id='my-project', verbose=True) + + def test_read_gbq_with_not_verbose_new_pandas_warns_deprecation(self): + import pkg_resources + min_bq_version = pkg_resources.parse_version('0.29.0') + pandas_version = pkg_resources.parse_version('0.23.0') + with pytest.warns(FutureWarning), \ + mock.patch( + 'pkg_resources.Distribution.parsed_version', + new_callable=mock.PropertyMock) as mock_version: + mock_version.side_effect = [min_bq_version, pandas_version] + gbq.read_gbq('SELECT 1', project_id='my-project', verbose=False) + + def test_read_gbq_wo_verbose_w_new_pandas_no_warnings(self, recwarn): + import pkg_resources + min_bq_version = pkg_resources.parse_version('0.29.0') + pandas_version = pkg_resources.parse_version('0.23.0') + with mock.patch( + 'pkg_resources.Distribution.parsed_version', + new_callable=mock.PropertyMock) as mock_version: + mock_version.side_effect = [min_bq_version, pandas_version] + gbq.read_gbq('SELECT 1', project_id='my-project') + assert len(recwarn) == 0 + + def test_read_gbq_with_verbose_old_pandas_no_warnings(self, recwarn): + import pkg_resources + min_bq_version = pkg_resources.parse_version('0.29.0') + pandas_version = pkg_resources.parse_version('0.22.0') + with mock.patch( + 'pkg_resources.Distribution.parsed_version', + new_callable=mock.PropertyMock) as mock_version: + mock_version.side_effect = [min_bq_version, pandas_version] + gbq.read_gbq('SELECT 1', project_id='my-project', verbose=True) + assert len(recwarn) == 0 + def test_should_read(project, credentials):