diff --git a/.coveragerc b/.coveragerc index d5e3f1dc..9b612b9b 100644 --- a/.coveragerc +++ b/.coveragerc @@ -17,6 +17,8 @@ # Generated by synthtool. DO NOT EDIT! [run] branch = True +omit = + pybigquery/requirements.py [report] fail_under = 100 diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml new file mode 100644 index 00000000..e2b39f94 --- /dev/null +++ b/.github/.OwlBot.lock.yaml @@ -0,0 +1,3 @@ +docker: + image: gcr.io/repo-automation-bots/owlbot-python:latest + digest: sha256:99d90d097e4a4710cc8658ee0b5b963f4426d0e424819787c3ac1405c9a26719 diff --git a/.github/.OwlBot.yaml b/.github/.OwlBot.yaml new file mode 100644 index 00000000..243bb8bf --- /dev/null +++ b/.github/.OwlBot.yaml @@ -0,0 +1,19 @@ +# Copyright 2021 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. + +docker: + image: gcr.io/repo-automation-bots/owlbot-python:latest + +begin-after-commit-hash: be22498ce258bf2d5fe12fd696d3ad9a2b6c430e + diff --git a/.kokoro/samples/python3.9/common.cfg b/.kokoro/samples/python3.9/common.cfg new file mode 100644 index 00000000..7e1b46d3 --- /dev/null +++ b/.kokoro/samples/python3.9/common.cfg @@ -0,0 +1,40 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "py-3.9" +} + +# Declare build specific Cloud project. +env_vars: { + key: "BUILD_SPECIFIC_GCLOUD_PROJECT" + value: "python-docs-samples-tests-py39" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-bigquery-sqlalchemy/.kokoro/test-samples.sh" +} + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" +} + +# Download secrets for samples +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "python-bigquery-sqlalchemy/.kokoro/trampoline.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.9/continuous.cfg b/.kokoro/samples/python3.9/continuous.cfg new file mode 100644 index 00000000..a1c8d975 --- /dev/null +++ b/.kokoro/samples/python3.9/continuous.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.9/periodic-head.cfg b/.kokoro/samples/python3.9/periodic-head.cfg new file mode 100644 index 00000000..f9cfcd33 --- /dev/null +++ b/.kokoro/samples/python3.9/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/.kokoro/samples/python3.9/periodic.cfg b/.kokoro/samples/python3.9/periodic.cfg new file mode 100644 index 00000000..50fec964 --- /dev/null +++ b/.kokoro/samples/python3.9/periodic.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "False" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.9/presubmit.cfg b/.kokoro/samples/python3.9/presubmit.cfg new file mode 100644 index 00000000..a1c8d975 --- /dev/null +++ b/.kokoro/samples/python3.9/presubmit.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1bbd7878..62eb5a77 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v4.0.1 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -26,6 +26,6 @@ repos: hooks: - id: black - repo: https://gitlab.com/pycqa/flake8 - rev: 3.9.1 + rev: 3.9.2 hooks: - id: flake8 diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d26b227..4ee155fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/pybigquery/#history +### [0.9.1](https://www.github.com/googleapis/python-bigquery-sqlalchemy/compare/v0.9.0...v0.9.1) (2021-06-25) + + +### Documentation + +* omit mention of Python 2.7 in 'CONTRIBUTING.rst' ([d52334c](https://www.github.com/googleapis/python-bigquery-sqlalchemy/commit/d52334c3290d8356a26e1c9fc54dae75854410c9)) + ## [0.9.0](https://www.github.com/googleapis/python-bigquery-sqlalchemy/compare/v0.8.0...v0.9.0) (2021-05-25) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 5a969313..6c221127 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -68,15 +68,12 @@ Using ``nox`` We use `nox `__ to instrument our tests. - To test your changes, run unit tests with ``nox``:: + $ nox -s unit - $ nox -s unit-2.7 - $ nox -s unit-3.8 - $ ... +- To run a single unit test:: -- Args to pytest can be passed through the nox command separated by a `--`. For - example, to run a single test:: + $ nox -s unit-3.9 -- -k - $ nox -s unit-3.8 -- -k .. note:: @@ -143,18 +140,16 @@ Running System Tests - To run system tests, you can execute:: # Run all system tests - $ nox -s system-3.8 - $ nox -s system-2.7 + $ nox -s system # Run a single system test - $ nox -s system-3.8 -- -k + $ nox -s system-3.9 -- -k .. note:: - System tests are only configured to run under Python 2.7 and - Python 3.8. For expediency, we do not run them in older versions - of Python 3. + System tests are only configured to run under Python 3.8 and 3.9. + For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local auth settings and change some configuration in your project to @@ -218,8 +213,8 @@ Supported versions can be found in our ``noxfile.py`` `config`_. .. _config: https://github.com/googleapis/python-bigquery-sqlalchemy/blob/master/noxfile.py -We also explicitly decided to support Python 3 beginning with version -3.6. Reasons for this include: +We also explicitly decided to support Python 3 beginning with version 3.6. +Reasons for this include: - Encouraging use of newest versions of Python 3 - Taking the lead of `prominent`_ open-source `projects`_ diff --git a/docs/conf.py b/docs/conf.py index d4eefe60..62dedd27 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -80,9 +80,9 @@ master_doc = "index" # General information about the project. -project = u"pybigquery" -copyright = u"2019, Google" -author = u"Google APIs" +project = "pybigquery" +copyright = "2019, Google" +author = "Google APIs" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -278,7 +278,7 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, "pybigquery.tex", u"pybigquery Documentation", author, "manual",) + (master_doc, "pybigquery.tex", "pybigquery Documentation", author, "manual",) ] # The name of an image file (relative to this directory) to place at the top of @@ -306,7 +306,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [(master_doc, "pybigquery", u"pybigquery Documentation", [author], 1,)] +man_pages = [(master_doc, "pybigquery", "pybigquery Documentation", [author], 1,)] # If true, show URL addresses after external links. # man_show_urls = False @@ -321,7 +321,7 @@ ( master_doc, "pybigquery", - u"pybigquery Documentation", + "pybigquery Documentation", author, "pybigquery", "pybigquery Library", @@ -349,6 +349,7 @@ "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None,), "grpc": ("https://grpc.github.io/grpc/python/", None), "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), } diff --git a/docs/multiprocessing.rst b/docs/multiprocessing.rst index 1cb29d4c..536d17b2 100644 --- a/docs/multiprocessing.rst +++ b/docs/multiprocessing.rst @@ -1,7 +1,7 @@ .. note:: - Because this client uses :mod:`grpcio` library, it is safe to + Because this client uses :mod:`grpc` library, it is safe to share instances across threads. In multiprocessing scenarios, the best practice is to create client instances *after* the invocation of - :func:`os.fork` by :class:`multiprocessing.Pool` or + :func:`os.fork` by :class:`multiprocessing.pool.Pool` or :class:`multiprocessing.Process`. diff --git a/noxfile.py b/noxfile.py index fd0f0101..d25f5877 100644 --- a/noxfile.py +++ b/noxfile.py @@ -48,8 +48,8 @@ ] # Error if a python version is missing -nox.options.error_on_missing_interpreters = True nox.options.stop_on_first_error = True +nox.options.error_on_missing_interpreters = True @nox.session(python=DEFAULT_PYTHON_VERSION) @@ -86,7 +86,7 @@ def install_alembic_for_python_38(session, constraints_path): """ install alembic for Python 3.8 unit and system tests - We don't require alembic and most tests should run without it, however + We do not require alembic and most tests should run without it, however - We run some unit tests (Python 3.8) to cover the alembic registration that happens when alembic is installed. @@ -105,6 +105,7 @@ def default(session): CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" ) session.install("mock", "pytest", "pytest-cov", "-c", constraints_path) + install_alembic_for_python_38(session, constraints_path) session.install("-e", ".", "-c", constraints_path) @@ -182,30 +183,23 @@ def system(session): @nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) def compliance(session): - """Run the system test suite.""" + """Run the SQLAlchemy dialect-compliance system tests""" constraints_path = str( CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" ) system_test_folder_path = os.path.join("tests", "sqlalchemy_dialect_compliance") - # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. if os.environ.get("RUN_COMPLIANCE_TESTS", "true") == "false": session.skip("RUN_COMPLIANCE_TESTS is set to false, skipping") - # Sanity check: Only run tests if the environment variable is set. if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", ""): session.skip("Credentials must be set via environment variable") - # Install pyopenssl for mTLS testing. if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": session.install("pyopenssl") - # Sanity check: only run tests if found. if not os.path.exists(system_test_folder_path): session.skip("Compliance tests were not found") - # Use pre-release gRPC for system tests. session.install("--pre", "grpcio") - # Install all test dependencies, then install this package into the - # virtualenv's dist-packages. session.install( "mock", "pytest", @@ -249,7 +243,7 @@ def docs(session): """Build the docs for this library.""" session.install("-e", ".") - session.install("sphinx", "alabaster", "recommonmark") + session.install("sphinx==4.0.1", "alabaster", "recommonmark") shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) session.run( @@ -271,7 +265,9 @@ def docfx(session): """Build the docfx yaml files for this library.""" session.install("-e", ".") - session.install("sphinx", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml") + session.install( + "sphinx==4.0.1", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml" + ) shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) session.run( diff --git a/owlbot.py b/owlbot.py new file mode 100644 index 00000000..9f3ddc6f --- /dev/null +++ b/owlbot.py @@ -0,0 +1,210 @@ +# Copyright 2021 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. + +"""This script is used to synthesize generated parts of this library.""" + +import pathlib + +import synthtool as s +from synthtool import gcp + + +REPO_ROOT = pathlib.Path(__file__).parent.absolute() + +common = gcp.CommonTemplates() + +# ---------------------------------------------------------------------------- +# Add templated files +# ---------------------------------------------------------------------------- +templated_files = common.py_library( + unit_test_python_versions=["3.6", "3.7", "3.8", "3.9"], + system_test_python_versions=["3.8", "3.9"], + cov_level=100 +) +s.move(templated_files, excludes=[ + # pybigquery was originally licensed MIT + "LICENSE" +]) + +# ---------------------------------------------------------------------------- +# Fixup files +# ---------------------------------------------------------------------------- + +s.replace( + [".coveragerc"], + "google/cloud/__init__.py", + "pybigquery/requirements.py", + ) + +s.replace( + ["noxfile.py"], + r"[\"']google[\"']", + '"pybigquery"', +) + +s.replace( + ["noxfile.py"], "google/cloud", "pybigquery", +) + +def place_before(path, text, *before_text, escape=None): + replacement = "\n".join(before_text) + "\n" + text + if escape: + for c in escape: + text = text.replace(c, '\\' + c) + s.replace([path], text, replacement) + +place_before( + "noxfile.py", + "SYSTEM_TEST_PYTHON_VERSIONS=", + "", + "# We're using two Python versions to test with sqlalchemy 1.3 and 1.4.", +) + +place_before( + "noxfile.py", + "nox.options.error_on_missing_interpreters = True", + "nox.options.stop_on_first_error = True", +) + +install_alembic_for_python_38 = ''' +def install_alembic_for_python_38(session, constraints_path): + """ + install alembic for Python 3.8 unit and system tests + + We do not require alembic and most tests should run without it, however + + - We run some unit tests (Python 3.8) to cover the alembic + registration that happens when alembic is installed. + + - We have a system test that demonstrates working with alembic and + proves that the things we think should work do work. :) + """ + if session.python == "3.8": + session.install("alembic", "-c", constraints_path) + + +''' + +place_before( + "noxfile.py", + "def default", + install_alembic_for_python_38, + ) + +place_before( + "noxfile.py", + ' session.install("-e", ".", ', + " install_alembic_for_python_38(session, constraints_path)", + escape='(') + +old_sessions = ''' + "unit", + "system", + "cover", + "lint", +''' + +new_sessions = ''' + "lint", + "unit", + "cover", + "system", + "compliance", +''' + +s.replace( ["noxfile.py"], old_sessions, new_sessions) + +compliance = ''' +@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) +def compliance(session): + """Run the SQLAlchemy dialect-compliance system tests""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + system_test_folder_path = os.path.join("tests", "sqlalchemy_dialect_compliance") + + if os.environ.get("RUN_COMPLIANCE_TESTS", "true") == "false": + session.skip("RUN_COMPLIANCE_TESTS is set to false, skipping") + if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", ""): + session.skip("Credentials must be set via environment variable") + if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": + session.install("pyopenssl") + if not os.path.exists(system_test_folder_path): + session.skip("Compliance tests were not found") + + session.install("--pre", "grpcio") + + session.install( + "mock", + "pytest", + "pytest-rerunfailures", + "google-cloud-testutils", + "-c", + constraints_path, + ) + session.install("-e", ".", "-c", constraints_path) + + session.run( + "py.test", + "-vv", + f"--junitxml=compliance_{session.python}_sponge_log.xml", + "--reruns=3", + "--reruns-delay=60", + "--only-rerun=403 Exceeded rate limits", + "--only-rerun=409 Already Exists", + "--only-rerun=404 Not found", + "--only-rerun=400 Cannot execute DML over a non-existent table", + system_test_folder_path, + *session.posargs, + ) + + +''' + +place_before( + "noxfile.py", + "@nox.session(python=DEFAULT_PYTHON_VERSION)\n" + "def cover(session):", + compliance, + escape="()", + ) + + + + +# Add DB config for SQLAlchemy dialect test suite. +# https://github.com/sqlalchemy/sqlalchemy/blob/master/README.dialects.rst +# https://github.com/googleapis/python-bigquery-sqlalchemy/issues/89 +s.replace( + ["setup.cfg"], + "universal = 1\n", + """universal = 1 + +[sqla_testing] +requirement_cls=pybigquery.requirements:Requirements +profile_file=.sqlalchemy_dialect_compliance-profiles.txt + +[tool:pytest] +addopts= --tb native -v -r fxX -p no:warnings +python_files=tests/*test_*.py +""" +) + +# ---------------------------------------------------------------------------- +# Final cleanup +# ---------------------------------------------------------------------------- + +s.shell.run(["nox", "-s", "blacken"], hide_output=False) +for noxfile in REPO_ROOT.glob("samples/**/noxfile.py"): + s.shell.run(["nox", "-s", "blacken"], cwd=noxfile.parent, hide_output=False) diff --git a/setup.cfg b/setup.cfg index 897c3eff..71e80492 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,7 +20,7 @@ universal = 1 [sqla_testing] requirement_cls=pybigquery.requirements:Requirements -profile_file=sqlalchemy_dialect_compliance-profiles.txt +profile_file=.sqlalchemy_dialect_compliance-profiles.txt [tool:pytest] addopts= --tb native -v -r fxX -p no:warnings diff --git a/setup.py b/setup.py index 99bee815..65f121ce 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ # Package metadata. name = "pybigquery" -version = "0.9.0" +version = "0.9.1" description = "SQLAlchemy dialect for BigQuery" # Should be one of: diff --git a/synth.metadata b/synth.metadata deleted file mode 100644 index c5a588f1..00000000 --- a/synth.metadata +++ /dev/null @@ -1,83 +0,0 @@ -{ - "sources": [ - { - "git": { - "name": ".", - "remote": "https://github.com/googleapis/python-bigquery-sqlalchemy.git", - "sha": "0a3151ba2cb5564ebc1bf2c920b4cab210cd73b8" - } - } - ], - "generatedFiles": [ - ".coveragerc", - ".flake8", - ".github/CONTRIBUTING.md", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/header-checker-lint.yml", - ".github/release-please.yml", - ".github/snippet-bot.yml", - ".gitignore", - ".kokoro/build.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/continuous.cfg", - ".kokoro/docker/docs/Dockerfile", - ".kokoro/docker/docs/fetch_gpg_keys.sh", - ".kokoro/docs/common.cfg", - ".kokoro/docs/docs-presubmit.cfg", - ".kokoro/docs/docs.cfg", - ".kokoro/populate-secrets.sh", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/publish-docs.sh", - ".kokoro/release.sh", - ".kokoro/release/common.cfg", - ".kokoro/release/release.cfg", - ".kokoro/samples/lint/common.cfg", - ".kokoro/samples/lint/continuous.cfg", - ".kokoro/samples/lint/periodic.cfg", - ".kokoro/samples/lint/presubmit.cfg", - ".kokoro/samples/python3.6/common.cfg", - ".kokoro/samples/python3.6/continuous.cfg", - ".kokoro/samples/python3.6/periodic-head.cfg", - ".kokoro/samples/python3.6/periodic.cfg", - ".kokoro/samples/python3.6/presubmit.cfg", - ".kokoro/samples/python3.7/common.cfg", - ".kokoro/samples/python3.7/continuous.cfg", - ".kokoro/samples/python3.7/periodic-head.cfg", - ".kokoro/samples/python3.7/periodic.cfg", - ".kokoro/samples/python3.7/presubmit.cfg", - ".kokoro/samples/python3.8/common.cfg", - ".kokoro/samples/python3.8/continuous.cfg", - ".kokoro/samples/python3.8/periodic-head.cfg", - ".kokoro/samples/python3.8/periodic.cfg", - ".kokoro/samples/python3.8/presubmit.cfg", - ".kokoro/test-samples-against-head.sh", - ".kokoro/test-samples-impl.sh", - ".kokoro/test-samples.sh", - ".kokoro/trampoline.sh", - ".kokoro/trampoline_v2.sh", - ".pre-commit-config.yaml", - ".trampolinerc", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.rst", - "MANIFEST.in", - "docs/_static/custom.css", - "docs/_templates/layout.html", - "docs/conf.py", - "docs/multiprocessing.rst", - "noxfile.py", - "renovate.json", - "scripts/decrypt-secrets.sh", - "scripts/readme-gen/readme_gen.py", - "scripts/readme-gen/templates/README.tmpl.rst", - "scripts/readme-gen/templates/auth.tmpl.rst", - "scripts/readme-gen/templates/auth_api_key.tmpl.rst", - "scripts/readme-gen/templates/install_deps.tmpl.rst", - "scripts/readme-gen/templates/install_portaudio.tmpl.rst", - "setup.cfg", - "testing/.gitignore" - ] -} \ No newline at end of file diff --git a/synth.py b/synth.py deleted file mode 100644 index 0cd34c15..00000000 --- a/synth.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2021 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. - -"""This script is used to synthesize generated parts of this library.""" - -import pathlib - -import synthtool as s -from synthtool import gcp - - -REPO_ROOT = pathlib.Path(__file__).parent.absolute() - -common = gcp.CommonTemplates() - -# ---------------------------------------------------------------------------- -# Add templated files -# ---------------------------------------------------------------------------- -templated_files = common.py_library( - unit_test_python_versions=["3.6", "3.7", "3.8", "3.9"], - system_test_python_versions=["3.8"], - cov_level=50 -) -s.move(templated_files, excludes=[ - # pybigquery was originally licensed MIT - "LICENSE" -]) - -# ---------------------------------------------------------------------------- -# Fixup files -# ---------------------------------------------------------------------------- - -s.replace( - ["noxfile.py"], - r"[\"']google[\"']", - '"pybigquery"', -) - -s.replace( - ["noxfile.py"], "google/cloud", "pybigquery", -) - -# Add DB config for SQLAlchemy dialect test suite. -# https://github.com/sqlalchemy/sqlalchemy/blob/master/README.dialects.rst -# https://github.com/googleapis/python-bigquery-sqlalchemy/issues/89 -s.replace( - ["setup.cfg"], - "universal = 1\n", - """universal = 1 - -[sqla_testing] -requirement_cls=pybigquery.requirements:Requirements -profile_file=.profiles.txt - -[db] -default=bigquery:// -bigquery=bigquery:// -""" -) - -# ---------------------------------------------------------------------------- -# Final cleanup -# ---------------------------------------------------------------------------- - -s.shell.run(["nox", "-s", "blacken"], hide_output=False) -for noxfile in REPO_ROOT.glob("samples/**/noxfile.py"): - s.shell.run(["nox", "-s", "blacken"], cwd=noxfile.parent, hide_output=False) diff --git a/tests/sqlalchemy_dialect_compliance/test_dialect_compliance.py b/tests/sqlalchemy_dialect_compliance/test_dialect_compliance.py index 5b8fc89d..e85dd541 100644 --- a/tests/sqlalchemy_dialect_compliance/test_dialect_compliance.py +++ b/tests/sqlalchemy_dialect_compliance/test_dialect_compliance.py @@ -114,8 +114,11 @@ def test_literal(self, literal_round_trip): # The base tests doesn't set up the literal properly, because # it doesn't pass its datatype to `literal`. - def literal(value): + def literal(value, type_=None): assert value == self.data + if type_ is not None: + assert type_ is self.datatype + import sqlalchemy.sql.sqltypes return sqlalchemy.sql.elements.literal(value, self.datatype)