Skip to content

Commit f795ed5

Browse files
committed
feat: Introduce compatibility with native namespace packages
1 parent 00561f8 commit f795ed5

File tree

10 files changed

+70
-81
lines changed

10 files changed

+70
-81
lines changed

google/__init__.py

Lines changed: 0 additions & 22 deletions
This file was deleted.

google/cloud/__init__.py

Lines changed: 0 additions & 22 deletions
This file was deleted.

google/cloud/sqlalchemy_spanner/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@
1414

1515
from .sqlalchemy_spanner import SpannerDialect
1616

17-
__all__ = (SpannerDialect,)
17+
from .version import __version__
18+
19+
20+
__all__ = (SpannerDialect, __version__)

google/cloud/sqlalchemy_spanner/sqlalchemy_spanner.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import pkg_resources
1615
import re
1716

1817
from alembic.ddl.base import (
@@ -45,6 +44,7 @@
4544
from google.cloud.spanner_v1.data_types import JsonObject
4645
from google.cloud import spanner_dbapi
4746
from google.cloud.sqlalchemy_spanner._opentelemetry_tracing import trace_call
47+
from google.cloud.sqlalchemy_spanner import version as sqlalchemy_spanner_version
4848
import sqlalchemy
4949

5050
USING_SQLACLCHEMY_20 = False
@@ -701,10 +701,11 @@ def create_connect_args(self, url):
701701
),
702702
url.database,
703703
)
704-
dist = pkg_resources.get_distribution("sqlalchemy-spanner")
705704
return (
706705
[match.group("instance"), match.group("database"), match.group("project")],
707-
{"user_agent": f"gl-{dist.project_name}/{dist.version}"},
706+
{
707+
"user_agent": f"gl-sqlalchemy-spanner/{sqlalchemy_spanner_version.__version__}"
708+
},
708709
)
709710

710711
@engine_to_connection
File renamed without changes.

setup.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import io
1616
import os
17+
import re
1718
import setuptools
1819

1920

@@ -34,14 +35,17 @@
3435
]
3536
}
3637

37-
BASE_DIR = os.path.dirname(__file__)
38-
VERSION_FILENAME = os.path.join(BASE_DIR, "version.py")
39-
PACKAGE_INFO = {}
40-
with open(VERSION_FILENAME) as f:
41-
exec(f.read(), PACKAGE_INFO)
42-
version = PACKAGE_INFO["__version__"]
43-
4438
package_root = os.path.abspath(os.path.dirname(__file__))
39+
40+
version = None
41+
42+
with open(
43+
os.path.join(package_root, "google/cloud/sqlalchemy_spanner/version.py")
44+
) as fp:
45+
version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read())
46+
assert len(version_candidates) == 1
47+
version = version_candidates[0]
48+
4549
readme_filename = os.path.join(package_root, "README.rst")
4650
with io.open(readme_filename, encoding="utf-8") as readme_file:
4751
readme = readme_file.read()
@@ -50,18 +54,13 @@
5054
# benchmarks, etc.
5155
packages = [
5256
package
53-
for package in setuptools.PEP420PackageFinder.find()
57+
for package in setuptools.find_namespace_packages()
5458
if package.startswith("google")
5559
]
5660

57-
# Determine which namespaces are needed.
58-
namespaces = ["google"]
59-
if "google.cloud" in packages:
60-
namespaces.append("google.cloud")
61-
6261
setuptools.setup(
6362
author="Google LLC",
64-
author_email="cloud-spanner-developers@googlegroups.com",
63+
author_email="googleapis-packages@google.com",
6564
classifiers=["Intended Audience :: Developers"],
6665
description=description,
6766
long_description=readme,
@@ -73,9 +72,8 @@
7372
install_requires=dependencies,
7473
extras_require=extras,
7574
name=name,
76-
namespace_packages=namespaces,
7775
packages=packages,
78-
url="https://github.com/cloudspannerecosystem/python-spanner-sqlalchemy",
76+
url="https://github.com/googleapis/python-spanner-sqlalchemy",
7977
version=version,
8078
include_package_data=True,
8179
zip_safe=False,

test/test_suite_13.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import decimal
1919
import operator
2020
import os
21-
import pkg_resources
2221
import pytest
2322
import random
2423
import time
@@ -126,6 +125,8 @@
126125
)
127126
from test._helpers import get_db_url, get_project
128127

128+
from google.cloud.sqlalchemy_spanner import version as sqlalchemy_spanner_version
129+
129130
config.test_schema = ""
130131

131132

@@ -1645,12 +1646,10 @@ class UserAgentTest(SpannerSpecificTestBase):
16451646
"""Check that SQLAlchemy dialect uses correct user agent."""
16461647

16471648
def test_user_agent(self):
1648-
dist = pkg_resources.get_distribution("sqlalchemy-spanner")
1649-
16501649
with self._engine.connect() as connection:
16511650
assert (
16521651
connection.connection.instance._client._client_info.user_agent
1653-
== f"gl-{dist.project_name}/{dist.version}"
1652+
== f"gl-sqlalchemy-spanner/{sqlalchemy_spanner_version.__version__}"
16541653
)
16551654

16561655

@@ -1702,7 +1701,6 @@ def setUp(self):
17021701

17031702
def test_offset_only(self):
17041703
for offset in [1, 7, 10, 100, 1000, 10000]:
1705-
17061704
with self._engine.connect().execution_options(read_only=True) as connection:
17071705
list(connection.execute(self._table.select().offset(offset)).fetchall())
17081706

test/test_suite_14.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import decimal
1919
import operator
2020
import os
21-
import pkg_resources
2221
import pytest
2322
import random
2423
import time
@@ -142,6 +141,9 @@
142141
)
143142
from test._helpers import get_db_url, get_project
144143

144+
from google.cloud.sqlalchemy_spanner import version as sqlalchemy_spanner_version
145+
146+
145147
config.test_schema = ""
146148

147149

@@ -556,7 +558,6 @@ def test_get_foreign_keys(self, connection, use_schema):
556558
def test_get_table_names(
557559
self, connection, order_by, include_plain, include_views, use_schema
558560
):
559-
560561
if use_schema:
561562
schema = config.test_schema
562563
else:
@@ -1913,12 +1914,10 @@ def setUp(self):
19131914
self._metadata = MetaData(bind=self._engine)
19141915

19151916
def test_user_agent(self):
1916-
dist = pkg_resources.get_distribution("sqlalchemy-spanner")
1917-
19181917
with self._engine.connect() as connection:
19191918
assert (
19201919
connection.connection.instance._client._client_info.user_agent
1921-
== "gl-" + dist.project_name + "/" + dist.version
1920+
== f"gl-sqlalchemy-spanner/{sqlalchemy_spanner_version.__version__}"
19221921
)
19231922

19241923

test/test_suite_20.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import decimal
1919
import operator
2020
import os
21-
import pkg_resources
2221
import pytest
2322
import random
2423
import time
@@ -151,6 +150,9 @@
151150
) # noqa: F401, F403
152151
from test._helpers import get_db_url, get_project
153152

153+
from google.cloud.sqlalchemy_spanner import version as sqlalchemy_spanner_version
154+
155+
154156
config.test_schema = ""
155157

156158

@@ -872,7 +874,6 @@ def test_get_multi_foreign_keys(
872874
scope=ObjectScope.DEFAULT,
873875
kind=ObjectKind.TABLE,
874876
):
875-
876877
"""
877878
SPANNER OVERRIDE:
878879
@@ -1088,7 +1089,6 @@ def test_get_foreign_keys(self, connection, use_schema):
10881089
(True, testing.requires.schemas), False, argnames="use_schema"
10891090
)
10901091
def test_get_table_names(self, connection, order_by, use_schema):
1091-
10921092
schema = None
10931093

10941094
_ignore_tables = [
@@ -1977,7 +1977,6 @@ def _round_trip(self, datatype, data):
19771977
assert isinstance(row[0], (long, int)) # noqa
19781978

19791979
def _huge_ints():
1980-
19811980
return testing.combinations(
19821981
2147483649, # 32 bits
19831982
2147483648, # 32 bits
@@ -2653,12 +2652,10 @@ def setUp(self):
26532652
self._metadata = MetaData()
26542653

26552654
def test_user_agent(self):
2656-
dist = pkg_resources.get_distribution("sqlalchemy-spanner")
2657-
26582655
with self._engine.connect() as connection:
26592656
assert (
26602657
connection.connection.instance._client._client_info.user_agent
2661-
== "gl-" + dist.project_name + "/" + dist.version
2658+
== f"gl-sqlalchemy-spanner/{sqlalchemy_spanner_version.__version__}"
26622659
)
26632660

26642661

test/unit/test_packaging.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright 2023 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
import subprocess
17+
import sys
18+
19+
20+
def test_namespace_package_compat(tmp_path):
21+
# The ``google`` namespace package should not be masked
22+
# by the presence of ``sqlalchemy-spanner``.
23+
google = tmp_path / "google"
24+
google.mkdir()
25+
google.joinpath("othermod.py").write_text("")
26+
env = dict(os.environ, PYTHONPATH=str(tmp_path))
27+
cmd = [sys.executable, "-m", "google.othermod"]
28+
subprocess.check_call(cmd, env=env)
29+
30+
# The ``google.cloud`` namespace package should not be masked
31+
# by the presence of ``sqlalchemy-spanner``.
32+
google_cloud = tmp_path / "google" / "cloud"
33+
google_cloud.mkdir()
34+
google_cloud.joinpath("othermod.py").write_text("")
35+
env = dict(os.environ, PYTHONPATH=str(tmp_path))
36+
cmd = [sys.executable, "-m", "google.cloud.othermod"]
37+
subprocess.check_call(cmd, env=env)

0 commit comments

Comments
 (0)