Repository: googleapis/python-logging

Issue:
DeprecationWarning for pkg_resources.declare_namespace("google.logging")
Starting from `setuptools==67.3.0`, it has started raising DeprecationWarning. Some libraries treat them as errors during testing.

See: https://setuptools.pypa.io/en/latest/history.html#v67-3-0.

```python
/lib/python3.11/site-packages/pkg_resources/__init__.py:2804: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('google.logging')`.
  Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages
    declare_namespace(pkg)
```

See similar discussion in https://github.com/matplotlib/matplotlib/issues/25244 and https://github.com/pypa/setuptools/pull/3434#issuecomment-1435697632. 

Also opened a similar issue in `google.cloud`: https://github.com/googleapis/python-storage/issues/1000.

Discussion:
parthea: Adding `do not merge` as there is an upcoming release freeze. This should be merged after the release freeze ends on November 29th.

Patch:
diff --git a/google/__init__.py b/google/__init__.py
deleted file mode 100644
index 0e1bc51..0000000
--- a/google/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2016 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.
-
-try:
-    import pkg_resources
-
-    pkg_resources.declare_namespace(__name__)
-except ImportError:
-    import pkgutil
-
-    __path__ = pkgutil.extend_path(__path__, __name__)
diff --git a/google/cloud/__init__.py b/google/cloud/__init__.py
deleted file mode 100644
index 0e1bc51..0000000
--- a/google/cloud/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2016 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.
-
-try:
-    import pkg_resources
-
-    pkg_resources.declare_namespace(__name__)
-except ImportError:
-    import pkgutil
-
-    __path__ = pkgutil.extend_path(__path__, __name__)
diff --git a/setup.py b/setup.py
index f43fd0b..e4a7127 100644
--- a/setup.py
+++ b/setup.py
@@ -55,14 +55,10 @@ with io.open(readme_filename, encoding="utf-8") as readme_file:
 
 packages = [
     package
-    for package in setuptools.PEP420PackageFinder.find()
+    for package in setuptools.find_namespace_packages()
     if package.startswith("google")
 ]
 
-namespaces = ["google"]
-if "google.cloud" in packages:
-    namespaces.append("google.cloud")
-
 setuptools.setup(
     name=name,
     version=version,
@@ -89,7 +85,6 @@ setuptools.setup(
     platforms="Posix; MacOS X; Windows",
     packages=packages,
     python_requires=">=3.7",
-    namespace_packages=namespaces,
     install_requires=dependencies,
     include_package_data=True,
     zip_safe=False,


Test patch:
diff --git a/tests/unit/test_packaging.py b/tests/unit/test_packaging.py
new file mode 100644
index 0000000..4369ca2
--- /dev/null
+++ b/tests/unit/test_packaging.py
@@ -0,0 +1,56 @@
+# Copyright 2023 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.
+
+import os
+import subprocess
+import sys
+
+
+def test_namespace_package_compat(tmp_path):
+    # The ``google`` namespace package should not be masked
+    # by the presence of ``google-cloud-logging``.
+
+    google = tmp_path / "google"
+    google.mkdir()
+    google.joinpath("othermod.py").write_text("")
+
+    google_otherpkg = tmp_path / "google" / "otherpkg"
+    google_otherpkg.mkdir()
+    google_otherpkg.joinpath("__init__.py").write_text("")
+
+    # The ``google.cloud`` namespace package should not be masked
+    # by the presence of ``google-cloud-logging``.
+    google_cloud = tmp_path / "google" / "cloud"
+    google_cloud.mkdir()
+    google_cloud.joinpath("othermod.py").write_text("")
+
+    google_cloud_otherpkg = tmp_path / "google" / "cloud" / "otherpkg"
+    google_cloud_otherpkg.mkdir()
+    google_cloud_otherpkg.joinpath("__init__.py").write_text("")
+
+    env = dict(os.environ, PYTHONPATH=str(tmp_path))
+
+    for pkg in [
+        "google.othermod",
+        "google.cloud.othermod",
+        "google.otherpkg",
+        "google.cloud.otherpkg",
+        "google.cloud.logging",
+    ]:
+        cmd = [sys.executable, "-c", f"import {pkg}"]
+        subprocess.check_output(cmd, env=env)
+
+    for module in ["google.othermod", "google.cloud.othermod"]:
+        cmd = [sys.executable, "-m", module]
+        subprocess.check_output(cmd, env=env)