internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: googleapis/python-bigquery

Issue:
Add create_table_clustered sample code
Add code snippet for creating clustered table.



Discussion:

Resolving patch:
diff --git a/samples/create_table_clustered.py b/samples/create_table_clustered.py
new file mode 100644
--- /dev/null
+++ b/samples/create_table_clustered.py
@@ -0,0 +1,42 @@
+# Copyright 2019 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
+#
+#     https://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.
+
+
+def create_table_clustered(table_id):
+
+    # [START bigquery_create_table_clustered]
+    from google.cloud import bigquery
+
+    # Construct a BigQuery client object.
+    client = bigquery.Client()
+
+    # TODO(developer): Set table_id to the ID of the table to create.
+    # table_id = "your-project.your_dataset.your_table_name"
+
+    schema = [
+        bigquery.SchemaField("full_name", "STRING"),
+        bigquery.SchemaField("city", "STRING"),
+        bigquery.SchemaField("zipcode", "INTEGER"),
+    ]
+
+    table = bigquery.Table(table_id, schema=schema)
+    table.clustering_fields = ["city", "zipcode"]
+    table = client.create_table(table)  # Make an API request.
+    print(
+        "Created clustered table {}.{}.{}".format(
+            table.project, table.dataset_id, table.table_id
+        )
+    )
+    # [END bigquery_create_table_clustered]
+    return table


Test patch:
diff --git a/samples/tests/test_create_table_clustered.py b/samples/tests/test_create_table_clustered.py
new file mode 100644
--- /dev/null
+++ b/samples/tests/test_create_table_clustered.py
@@ -0,0 +1,22 @@
+# Copyright 2019 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
+#
+#     https://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.
+
+from .. import create_table_clustered
+
+
+def test_create_table_clustered(capsys, random_table_id):
+    table = create_table_clustered.create_table_clustered(random_table_id)
+    out, _ = capsys.readouterr()
+    assert "Created clustered table {}".format(random_table_id) in out
+    assert table.clustering_fields == ["city", "zipcode"]
Repository: googleapis/python-bigquery

Issue:
Remove uses of get_distribution to better support package vendoring
`get_distribution` doesn't function when packages are vendored. We should remove uses of this function.

https://github.com/googleapis/python-bigquery/blob/d1eb8b3dcc789916c5d3ba8464f62b1f8bef35ff/google/cloud/bigquery/__init__.py#L33

See: https://github.com/googleapis/python-api-core/pull/80 as an example of how to fix this using a "version" module. Release tooling is being updated to support this method.


Discussion:

Resolving patch:
diff --git a/google/cloud/bigquery/__init__.py b/google/cloud/bigquery/__init__.py
--- a/google/cloud/bigquery/__init__.py
+++ b/google/cloud/bigquery/__init__.py
@@ -28,9 +28,9 @@
 """
 
 
-from pkg_resources import get_distribution
+from google.cloud.bigquery import version as bigquery_version
 
-__version__ = get_distribution("google-cloud-bigquery").version
+__version__ = bigquery_version.__version__
 
 from google.cloud.bigquery.client import Client
 from google.cloud.bigquery.dataset import AccessEntry
diff --git a/google/cloud/bigquery/version.py b/google/cloud/bigquery/version.py
new file mode 100644
--- /dev/null
+++ b/google/cloud/bigquery/version.py
@@ -0,0 +1,15 @@
+# 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.
+
+__version__ = "2.1.0"
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@
 
 name = "google-cloud-bigquery"
 description = "Google BigQuery API client library"
-version = "2.1.0"
+
 # Should be one of:
 # 'Development Status :: 3 - Alpha'
 # 'Development Status :: 4 - Beta'
@@ -83,6 +83,11 @@
 with io.open(readme_filename, encoding="utf-8") as readme_file:
     readme = readme_file.read()
 
+version = {}
+with open(os.path.join(package_root, "google/cloud/bigquery/version.py")) as fp:
+    exec(fp.read(), version)
+version = version["__version__"]
+
 # Only include packages under the 'google' namespace. Do not include tests,
 # benchmarks, etc.
 packages = [


Test patch:
Repository: googleapis/python-bigquery

Issue:
docs: add QueryPlanEntry and QueryPlanEntryStep to documentation
 **Is your feature request related to a problem? Please describe.**

The documentation for [QueryJob.query_plan](https://googleapis.dev/python/bigquery/latest/generated/google.cloud.bigquery.job.QueryJob.html#google.cloud.bigquery.job.QueryJob.query_plan) shows the return type as `List[QueryPlanEntry]`, but `QueryPlanEntry` is not a clickable link like other return types (example: [QueryJob.ddl_target_table](https://googleapis.dev/python/bigquery/latest/generated/google.cloud.bigquery.job.QueryJob.html#google.cloud.bigquery.job.QueryJob.ddl_target_table) has a clickable link to [TableReference](https://googleapis.dev/python/bigquery/latest/generated/google.cloud.bigquery.table.TableReference.html#google.cloud.bigquery.table.TableReference)).

 **Describe the solution you'd like**

* Add a reference to `QueryPlanEntry` to the job-related types in [reference.rst](https://github.com/googleapis/python-bigquery/blob/master/docs/reference.rst).
* Verify that the `query_plan` property docs now render with a link.



Discussion:

Resolving patch:
diff --git a/google/cloud/bigquery/job.py b/google/cloud/bigquery/job.py
--- a/google/cloud/bigquery/job.py
+++ b/google/cloud/bigquery/job.py
@@ -2844,7 +2844,7 @@ def query_plan(self):
         https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobStatistics2.FIELDS.query_plan
 
         Returns:
-            List[QueryPlanEntry]:
+            List[google.cloud.bigquery.job.QueryPlanEntry]:
                 mappings describing the query plan, or an empty list
                 if the query has not yet completed.
         """
@@ -3418,7 +3418,6 @@ class QueryPlanEntryStep(object):
 
     Args:
         kind (str): step type.
-
         substeps (List): names of substeps.
     """
 
@@ -3434,7 +3433,8 @@ def from_api_repr(cls, resource):
             resource (Dict): JSON representation of the entry.
 
         Returns:
-            QueryPlanEntryStep: new instance built from the resource.
+            google.cloud.bigquery.job.QueryPlanEntryStep:
+                New instance built from the resource.
         """
         return cls(kind=resource.get("kind"), substeps=resource.get("substeps", ()))
 
@@ -3464,7 +3464,7 @@ def from_api_repr(cls, resource):
                 ExplainQueryStage representation returned from API.
 
         Returns:
-            google.cloud.bigquery.QueryPlanEntry:
+            google.cloud.bigquery.job.QueryPlanEntry:
                 Query plan entry parsed from ``resource``.
         """
         entry = cls()


Test patch:
Repository: googleapis/python-bigquery

Issue:
fix(dbapi): avoid running % format when no query parameters are passed
 **Is your feature request related to a problem? Please describe.**

It is unexpected to get format errors when a string contains `%`, but there are no query parameters in the query.

https://github.com/mxmzdlv/pybigquery/issues/72

 **Describe the solution you'd like**

In addition to checking if `parameters` is none, check if `len(parameters) == 0` to avoid unnecessary format operations.

https://github.com/googleapis/python-bigquery/blob/dca2e4ca7c2ae183ac4bb60f653d425a43a86bea/google/cloud/bigquery/dbapi/cursor.py#L444



Discussion:

Resolving patch:
diff --git a/google/cloud/bigquery/dbapi/cursor.py b/google/cloud/bigquery/dbapi/cursor.py
--- a/google/cloud/bigquery/dbapi/cursor.py
+++ b/google/cloud/bigquery/dbapi/cursor.py
@@ -441,7 +441,7 @@ def _format_operation(operation, parameters=None):
             if a parameter used in the operation is not found in the
             ``parameters`` argument.
     """
-    if parameters is None:
+    if parameters is None or len(parameters) == 0:
         return operation
 
     if isinstance(parameters, collections_abc.Mapping):


Test patch:
diff --git a/tests/unit/test_dbapi_cursor.py b/tests/unit/test_dbapi_cursor.py
--- a/tests/unit/test_dbapi_cursor.py
+++ b/tests/unit/test_dbapi_cursor.py
@@ -601,3 +601,9 @@ def test__format_operation_w_too_short_sequence(self):
             "SELECT %s, %s;",
             ("hello",),
         )
+
+    def test__format_operation_w_empty_dict(self):
+        from google.cloud.bigquery.dbapi import cursor
+
+        formatted_operation = cursor._format_operation("SELECT '%f'", {})
+        self.assertEqual(formatted_operation, "SELECT '%f'")
Repository: googleapis/python-bigquery

Issue:
Make Model constructor robust against new model types
Follow-up to https://github.com/googleapis/python-bigquery/issues/293

[model_type](https://googleapis.dev/python/bigquery/latest/generated/google.cloud.bigquery.model.Model.html#google.cloud.bigquery.model.Model.model_type) appears to be the only enum. Maybe we pull this out of the `_proto` resource and save it as a string, instead?

Alternatively, maybe if we fail to parse, we can set to MODEL_TYPE_UNSPECIFIED?


Discussion:

Resolving patch:
diff --git a/google/cloud/bigquery/model.py b/google/cloud/bigquery/model.py
--- a/google/cloud/bigquery/model.py
+++ b/google/cloud/bigquery/model.py
@@ -305,9 +305,15 @@ def from_api_repr(cls, resource):
             start_time = datetime_helpers.from_microseconds(1e3 * float(start_time))
             training_run["startTime"] = datetime_helpers.to_rfc3339(start_time)
 
-        this._proto = json_format.ParseDict(
-            resource, types.Model()._pb, ignore_unknown_fields=True
-        )
+        try:
+            this._proto = json_format.ParseDict(
+                resource, types.Model()._pb, ignore_unknown_fields=True
+            )
+        except json_format.ParseError:
+            resource["modelType"] = "MODEL_TYPE_UNSPECIFIED"
+            this._proto = json_format.ParseDict(
+                resource, types.Model()._pb, ignore_unknown_fields=True
+            )
         return this
 
     def _build_resource(self, filter_fields):


Test patch:
diff --git a/tests/unit/model/test_model.py b/tests/unit/model/test_model.py
--- a/tests/unit/model/test_model.py
+++ b/tests/unit/model/test_model.py
@@ -186,6 +186,23 @@ def test_from_api_repr_w_unknown_fields(target_class):
     assert got._properties is resource
 
 
+def test_from_api_repr_w_unknown_type(target_class):
+    from google.cloud.bigquery import ModelReference
+
+    resource = {
+        "modelReference": {
+            "projectId": "my-project",
+            "datasetId": "my_dataset",
+            "modelId": "my_model",
+        },
+        "modelType": "BE_A_GOOD_ROLE_MODEL",
+    }
+    got = target_class.from_api_repr(resource)
+    assert got.reference == ModelReference.from_string("my-project.my_dataset.my_model")
+    assert got.model_type == 0
+    assert got._properties is resource
+
+
 @pytest.mark.parametrize(
     "resource,filter_fields,expected",
     [
Repository: googleapis/python-bigquery

Issue:
Integration test with pyarrow nightly builds?
I'm not sure how difficult it would be to add, but it might be useful to regularly test the library against pyarrow nightly build's to catch regressions before they make their way into releases.





Discussion:
@emkornfield That is something that is actually being discussed recently in a wider scope - the goal is to prevent regressions (not just in BigQuery) when a new version of a dependency (either Google's or from a 3rd party) breaks a client library that depends on it. It has already happened several times, and _will_ happen again.

If/when such testing is in place, it would probably not be difficult to also include testing pre-release versions of a few selected 3rd-party dependencies, and `pyarrow` is probably a good candidate for that, considering its complexity.

I will keep this open for visibility, and thanks for suggesting it!
@crwilcox This seems like it'd fit with the pre-release tests infrastructure you mentioned in the Python Client Libs meeting today.

Resolving patch:
diff --git a/noxfile.py b/noxfile.py
--- a/noxfile.py
+++ b/noxfile.py
@@ -168,6 +168,38 @@ def cover(session):
     session.run("coverage", "erase")
 
 
+@nox.session(python="3.8")
+def prerelease_deps(session):
+    """Run all tests with prerelease versions of dependencies installed.
+
+    https://github.com/googleapis/python-bigquery/issues/95
+    """
+    # PyArrow prerelease packages are published to an alternative PyPI host.
+    # https://arrow.apache.org/docs/python/install.html#installing-nightly-packages
+    session.install(
+        "--extra-index-url", "https://pypi.fury.io/arrow-nightlies/", "--pre", "pyarrow"
+    )
+    session.install("--pre", "grpcio", "pandas")
+    session.install(
+        "mock",
+        "pytest",
+        "google-cloud-testutils",
+        "pytest-cov",
+        "freezegun",
+        "IPython",
+    )
+    session.install("-e", ".[all]")
+
+    # Print out prerelease package versions.
+    session.run("python", "-c", "import grpc; print(grpc.__version__)")
+    session.run("python", "-c", "import pandas; print(pandas.__version__)")
+    session.run("python", "-c", "import pyarrow; print(pyarrow.__version__)")
+
+    # Run all tests, except a few samples tests which require extra dependencies.
+    session.run("py.test", "tests")
+    session.run("py.test", "samples/tests")
+
+
 @nox.session(python="3.8")
 def lint(session):
     """Run linters.


Test patch:
Repository: googleapis/python-bigquery

Issue:
Simplify AutoStrEnum definition in Jupyter magic's argument parser
The current definition of [AutoStrEnum](https://github.com/googleapis/python-bigquery/blob/0337ea0bde966c3ccb94960493a6fa6f2bee49b4/google/cloud/bigquery/magics/line_arg_parser/lexer.py#L139-L167) is rather complicated. With the library now only supporting Python 3.6+, we can simplify it and just use the `_generate_next_value_()` hook.


Discussion:

Resolving patch:
diff --git a/google/cloud/bigquery/magics/line_arg_parser/lexer.py b/google/cloud/bigquery/magics/line_arg_parser/lexer.py
--- a/google/cloud/bigquery/magics/line_arg_parser/lexer.py
+++ b/google/cloud/bigquery/magics/line_arg_parser/lexer.py
@@ -136,40 +136,17 @@
 )
 
 
-# The _generate_next_value_() enum hook is only available in Python 3.6+, thus we
-# need to do some acrobatics to implement an "auto str enum" base class. Implementation
-# based on the recipe provided by the very author of the Enum library:
-# https://stackoverflow.com/a/32313954/5040035
-class StrEnumMeta(enum.EnumMeta):
-    @classmethod
-    def __prepare__(metacls, name, bases, **kwargs):
-        # Having deterministic enum members definition order is nice.
-        return OrderedDict()
+class AutoStrEnum(str, enum.Enum):
+    """Base enum class for for name=value str enums."""
 
-    def __new__(metacls, name, bases, oldclassdict):
-        # Scan through the declared enum members and convert any value that is a plain
-        # empty tuple into a `str` of the name instead.
-        newclassdict = enum._EnumDict()
-        for key, val in oldclassdict.items():
-            if val == ():
-                val = key
-            newclassdict[key] = val
-        return super(StrEnumMeta, metacls).__new__(metacls, name, bases, newclassdict)
+    def _generate_next_value_(name, start, count, last_values):
+        return name
 
 
-# The @six.add_metaclass decorator does not work, Enum complains about _sunder_ names,
-# and we cannot use class syntax directly, because the Python 3 version would cause
-# a syntax error under Python 2.
-AutoStrEnum = StrEnumMeta(
-    "AutoStrEnum",
-    (str, enum.Enum),
-    {"__doc__": "Base enum class for for name=value str enums."},
-)
-
 TokenType = AutoStrEnum(
     "TokenType",
     [
-        (name, name)
+        (name, enum.auto())
         for name in itertools.chain.from_iterable(token_types.values())
         if not name.startswith("GOTO_")
     ],
@@ -177,10 +154,10 @@ def __new__(metacls, name, bases, oldclassdict):
 
 
 class LexerState(AutoStrEnum):
-    PARSE_POS_ARGS = ()  # parsing positional arguments
-    PARSE_NON_PARAMS_OPTIONS = ()  # parsing options other than "--params"
-    PARSE_PARAMS_OPTION = ()  # parsing the "--params" option
-    STATE_END = ()
+    PARSE_POS_ARGS = enum.auto()  # parsing positional arguments
+    PARSE_NON_PARAMS_OPTIONS = enum.auto()  # parsing options other than "--params"
+    PARSE_PARAMS_OPTION = enum.auto()  # parsing the "--params" option
+    STATE_END = enum.auto()
 
 
 class Lexer(object):


Test patch:
Repository: googleapis/python-bigquery

Issue:
Bound the maximum supported Python version
Related: #462.

The BigQuery library does not support Python 3.9 yet, as the `bqstorage` and `pandas` extras are blocked by the `pyarrow` dependency. Pyarrow [added](https://issues.apache.org/jira/browse/ARROW-10224) the Python 3.9 support, but the change has not been released yet (awaiting `pyarrow==3.0.0`).

We need to reflect this in `setup.py`'s ``python_requires`.


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -33,7 +33,6 @@
     "proto-plus >= 1.10.0",
     "google-cloud-core >= 1.4.1, < 2.0dev",
     "google-resumable-media >= 0.6.0, < 2.0dev",
-    "six >=1.13.0,< 2.0.0dev",
     "protobuf >= 3.12.0",
 ]
 extras = {
@@ -121,7 +120,7 @@
     namespace_packages=namespaces,
     install_requires=dependencies,
     extras_require=extras,
-    python_requires=">=3.6",
+    python_requires=">=3.6, <3.9",
     include_package_data=True,
     zip_safe=False,
 )


Test patch:
Repository: googleapis/python-bigquery

Issue:
Support for with statement for Client class
 **Is your feature request related to a problem? Please describe.**
Currently, the Client class does not support with statement. Supporting with statement would make programmers easy to write and maintenance their code.

 **Describe the solution you'd like**
Add `__enter__` and `__exit__` methods to enable with statement. Works as following would be perfect.
```
with bigquery.Client(location='Asia/Tokyo') as client:
    query_job = client.query("SELECT CURRENT_DATE('Asia/Tokyo');")
```


Discussion:
@nnaka2992 What would be the expected behavior here?

Presumably, `__enter__()` would simply return the client instance, i.e. `self`, and `__exit__()` would invoke the client's `close()` method?

This could be added, yes, thanks for the suggestion.

Resolving patch:
diff --git a/google/cloud/bigquery/client.py b/google/cloud/bigquery/client.py
--- a/google/cloud/bigquery/client.py
+++ b/google/cloud/bigquery/client.py
@@ -3423,6 +3423,12 @@ def schema_to_json(self, schema_list, destination):
         with open(destination, mode="w") as file_obj:
             return self._schema_to_json_file_object(json_schema_list, file_obj)
 
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self.close()
+
 
 # pylint: disable=unused-argument
 def _item_to_project(iterator, resource):


Test patch:
diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py
--- a/tests/unit/test_client.py
+++ b/tests/unit/test_client.py
@@ -7218,6 +7218,28 @@ def test_list_rows_error(self):
         with self.assertRaises(TypeError):
             client.list_rows(1)
 
+    def test_context_manager_enter_returns_itself(self):
+        creds = _make_credentials()
+        http = object()
+        client = self._make_one(project=self.PROJECT, credentials=creds, _http=http)
+
+        with mock.patch.object(client, "close"), client as context_var:
+            pass
+
+        self.assertIs(client, context_var)
+
+    def test_context_manager_exit_closes_client(self):
+        creds = _make_credentials()
+        http = object()
+        client = self._make_one(project=self.PROJECT, credentials=creds, _http=http)
+
+        fake_close = mock.Mock()
+        with mock.patch.object(client, "close", fake_close):
+            with client:
+                pass
+
+        fake_close.assert_called_once()
+
 
 class Test_make_job_id(unittest.TestCase):
     def _call_fut(self, job_id, prefix=None):
Repository: googleapis/python-bigquery

Issue:
loosen opentelemetry dependencies
See Spanner PR: https://github.com/googleapis/python-spanner/pull/298


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -53,9 +53,9 @@
     "bignumeric_type": ["pyarrow >= 3.0.0, < 4.0dev"],
     "tqdm": ["tqdm >= 4.7.4, <5.0.0dev"],
     "opentelemetry": [
-        "opentelemetry-api==0.11b0",
-        "opentelemetry-sdk==0.11b0",
-        "opentelemetry-instrumentation==0.11b0",
+        "opentelemetry-api >= 0.11b0",
+        "opentelemetry-sdk >= 0.11b0",
+        "opentelemetry-instrumentation >= 0.11b0",
     ],
 }
 


Test patch: