Skip to content

Commit 083da11

Browse files
feat: introduce compatibility with native namespace packages (#906)
1 parent 33dc2d7 commit 083da11

File tree

9 files changed

+75
-78
lines changed

9 files changed

+75
-78
lines changed

.mypy.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
python_version = 3.8
33
warn_unused_configs = True
44
plugins = sqlmypy
5+
namespace_packages = True
56

67
[mypy-google.auth.*]
78
ignore_missing_imports = True

google/__init__.py

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

google/cloud/__init__.py

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

google/cloud/sql/__init__.py

Whitespace-only changes.

google/cloud/sql/connector/__init__.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,10 @@
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
"""
16-
from .connector import Connector, create_async_connector
17-
from .instance import IPTypes
1816

17+
from google.cloud.sql.connector.connector import Connector, create_async_connector
18+
from google.cloud.sql.connector.instance import IPTypes
19+
from google.cloud.sql.connector.version import __version__
1920

20-
__ALL__ = [create_async_connector, Connector, IPTypes]
2121

22-
try:
23-
import pkg_resources
24-
25-
pkg_resources.declare_namespace(__name__)
26-
except ImportError:
27-
import pkgutil
28-
29-
__path__ = pkgutil.extend_path(__path__, __name__)
22+
__all__ = ["__version__", "create_async_connector", "Connector", "IPTypes"]

noxfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def lint(session):
4242
"google",
4343
"tests",
4444
)
45-
session.run("mypy", "google", "tests")
45+
session.run("mypy", "-p", "google", "--show-traceback")
4646
session.run("python", "setup.py", "sdist")
4747
session.run("twine", "check", "dist/*")
4848

requirements-test.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ flake8-annotations==2.9.1
99
black==23.11.0
1010
mypy==0.982
1111
sqlalchemy-stubs==0.4
12-
types-pkg-resources==0.1.3
1312
types-PyMySQL==1.1.0.1
1413
types-mock==5.1.0.2
1514
twine==4.0.2

setup.py

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,8 @@
1313
# limitations under the License.
1414
import io
1515
import os
16-
from setuptools import setup, find_packages
1716

18-
package_root = os.path.abspath(os.path.dirname(__file__))
19-
20-
readme_filename = os.path.join(package_root, "README.md")
21-
with io.open(readme_filename, encoding="utf-8") as readme_file:
22-
readme = readme_file.read()
23-
24-
packages = [package for package in find_packages() if package.startswith("google")]
25-
26-
# Determine which namespaces are needed.
27-
namespaces = ["google"]
28-
if "google.cloud" in packages:
29-
namespaces.append("google.cloud")
17+
from setuptools import find_namespace_packages, setup
3018

3119
name = "cloud-sql-python-connector"
3220
description = (
@@ -35,20 +23,32 @@
3523
" permissions to connect to a Cloud SQL database without having"
3624
" to manually allowlist IPs or manage SSL certificates."
3725
)
38-
39-
version = {}
40-
with open("google/cloud/sql/connector/version.py") as fp:
41-
exec(fp.read(), version)
42-
version = version["__version__"]
43-
4426
release_status = "Development Status :: 5 - Production/Stable"
45-
core_dependencies = [
27+
dependencies = [
4628
"aiohttp",
4729
"cryptography>=38.0.3",
4830
"Requests",
4931
"google-auth",
5032
]
5133

34+
package_root = os.path.abspath(os.path.dirname(__file__))
35+
36+
readme_filename = os.path.join(package_root, "README.md")
37+
with io.open(readme_filename, encoding="utf-8") as readme_file:
38+
readme = readme_file.read()
39+
40+
version = {}
41+
with open(os.path.join(package_root, "google/cloud/sql/connector/version.py")) as fp:
42+
exec(fp.read(), version)
43+
version = version["__version__"]
44+
45+
# Only include packages under the 'google' namespace. Do not include tests,
46+
# samples, etc.
47+
packages = [
48+
package for package in find_namespace_packages() if package.startswith("google")
49+
]
50+
51+
5252
setup(
5353
name=name,
5454
version=version,
@@ -71,13 +71,12 @@
7171
],
7272
platforms="Posix; MacOS X; Windows",
7373
packages=packages,
74-
namespace_packages=namespaces,
75-
install_requires=core_dependencies,
74+
install_requires=dependencies,
7675
extras_require={
7776
"pymysql": ["PyMySQL>=1.1.0"],
7877
"pg8000": ["pg8000>=1.30.3"],
7978
"pytds": ["python-tds>=1.13.0"],
80-
"asyncpg": ["asyncpg>=0.29.0"]
79+
"asyncpg": ["asyncpg>=0.29.0"],
8180
},
8281
python_requires=">=3.8",
8382
include_package_data=True,

tests/unit/test_packaging.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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 pathlib
17+
import subprocess
18+
import sys
19+
20+
21+
def test_namespace_package_compat(tmp_path: pathlib.PosixPath) -> None:
22+
# The ``google`` namespace package should not be masked
23+
# by the presence of ``cloud-sql-python-connector``.
24+
google = tmp_path / "google"
25+
google.mkdir()
26+
google.joinpath("othermod.py").write_text("")
27+
env = dict(os.environ, PYTHONPATH=str(tmp_path))
28+
cmd = [sys.executable, "-m", "google.othermod"]
29+
subprocess.check_call(cmd, env=env)
30+
31+
# The ``google.cloud`` namespace package should not be masked
32+
# by the presence of ``cloud-sql-python-connector``.
33+
google_cloud = tmp_path / "google" / "cloud"
34+
google_cloud.mkdir()
35+
google_cloud.joinpath("othermod.py").write_text("")
36+
env = dict(os.environ, PYTHONPATH=str(tmp_path))
37+
cmd = [sys.executable, "-m", "google.cloud.othermod"]
38+
subprocess.check_call(cmd, env=env)
39+
40+
# The ``google.cloud.sql`` namespace package should not be masked
41+
# by the presence of ``cloud-sql-python-connector``.
42+
google_cloud_sql = tmp_path / "google" / "cloud" / "sql"
43+
google_cloud_sql.mkdir()
44+
google_cloud_sql.joinpath("othermod.py").write_text("")
45+
env = dict(os.environ, PYTHONPATH=str(tmp_path))
46+
cmd = [sys.executable, "-m", "google.cloud.sql.othermod"]
47+
subprocess.check_call(cmd, env=env)

0 commit comments

Comments
 (0)