Repository: googleapis/google-cloud-python

Issue:
PubSub 0.37.1 Subscription Client is Broken
Hi,

I encountered the following error.

```
  File "/******/PubsubAccessor.py", line 129, in create_subscriber_client
    credentials=credentials,
  File "/******/lib/python2.7/site-packages/google/cloud/pubsub_v1/gapic/subscriber_client.py", line 188, in __init__
    self.iam_policy_stub = (iam_policy_pb2.IAMPolicyStub(channel))
  File "/******/lib/python2.7/site-packages/google/iam/v1/iam_policy_pb2.py", line 344, in __init__
    self.SetIamPolicy = channel.unary_unary(
AttributeError: 'NoneType' object has no attribute 'unary_unary'
```

This problem did not occur in 0.35.4.
I checked the commit log and found a strange part.

https://github.com/GoogleCloudPlatform/google-cloud-python/commit/371333a51165e99d4d02876b1ef133618485b6fc#diff-e221f62050dd418b49b113c7909d0ea2L129

Channel initialization processing has been deleted.

https://github.com/GoogleCloudPlatform/google-cloud-python/commit/371333a51165e99d4d02876b1ef133618485b6fc#diff-e221f62050dd418b49b113c7909d0ea2R188

However, implementations using channel remain.

Thanks,
Kazutomo





Discussion:
@theacodes I believe you have the state to point this issue in the right direction.
@lukesneeringer 

Lines 188 and 189 in `subscriber_client.py` should not be there.
As best as I can tell, [gapic-generator does not write them](https://github.com/googleapis/gapic-generator/blob/master/src/main/resources/com/google/api/codegen/py/main.snip#L134-L136), so this was probably an incomplete sync of some kind? If you re-generate, you should get a file without those lines. (A similar edit applies to `publisher_client.py`.)

Resolving patch:
diff --git a/pubsub/google/cloud/pubsub_v1/gapic/publisher_client.py b/pubsub/google/cloud/pubsub_v1/gapic/publisher_client.py
--- a/pubsub/google/cloud/pubsub_v1/gapic/publisher_client.py
+++ b/pubsub/google/cloud/pubsub_v1/gapic/publisher_client.py
@@ -24,6 +24,7 @@
 import google.api_core.path_template
 import google.api_core.grpc_helpers
 import google.api_core.page_iterator
+import google.api_core.path_template
 import grpc
 
 from google.cloud.pubsub_v1.gapic import publisher_client_config
@@ -164,9 +165,6 @@ def __init__(self,
                 credentials=credentials,
             )
 
-        self.iam_policy_stub = (iam_policy_pb2.IAMPolicyStub(channel))
-        self.publisher_stub = (pubsub_pb2_grpc.PublisherStub(channel))
-
         if client_info is None:
             client_info = (
                 google.api_core.gapic_v1.client_info.DEFAULT_CLIENT_INFO)
diff --git a/pubsub/google/cloud/pubsub_v1/gapic/subscriber_client.py b/pubsub/google/cloud/pubsub_v1/gapic/subscriber_client.py
--- a/pubsub/google/cloud/pubsub_v1/gapic/subscriber_client.py
+++ b/pubsub/google/cloud/pubsub_v1/gapic/subscriber_client.py
@@ -23,6 +23,7 @@
 import google.api_core.gapic_v1.method
 import google.api_core.grpc_helpers
 import google.api_core.page_iterator
+import google.api_core.path_template
 import google.api_core.protobuf_helpers
 import grpc
 
@@ -185,9 +186,6 @@ def __init__(self,
                 credentials=credentials,
             )
 
-        self.iam_policy_stub = (iam_policy_pb2.IAMPolicyStub(channel))
-        self.subscriber_stub = (pubsub_pb2_grpc.SubscriberStub(channel))
-
         if client_info is None:
             client_info = (
                 google.api_core.gapic_v1.client_info.DEFAULT_CLIENT_INFO)
diff --git a/pubsub/synth.py b/pubsub/synth.py
--- a/pubsub/synth.py
+++ b/pubsub/synth.py
@@ -53,26 +53,6 @@
     ' pubsub_v1',
     ' subscriber_client')
 
-# iam_policy_pb2_grpc doesn't exist.
-s.replace(
-    ['google/cloud/pubsub_v1/gapic/publisher_client.py',
-     'google/cloud/pubsub_v1/gapic/subscriber_client.py'],
-    'from google.iam.v1 import iam_policy_pb2_grpc\n',
-    '')
-s.replace(
-    ['google/cloud/pubsub_v1/gapic/transports/publisher_grpc_transport.py',
-     'google/cloud/pubsub_v1/gapic/transports/subscriber_grpc_transport.py'],
-    'from google.iam.v1 import iam_policy_pb2_grpc\n',
-    'from google.iam.v1 import iam_policy_pb2\n')
-s.replace(
-    'google/cloud/pubsub_v1/gapic/transports/publisher_grpc_transport.py',
-    'iam_policy_pb2_grpc',
-    'iam_policy_pb2')
-s.replace(
-    'google/cloud/pubsub_v1/gapic/transports/subscriber_grpc_transport.py',
-    'iam_policy_pb2_grpc',
-    'iam_policy_pb2')
-
 # DEFAULT SCOPES are being used. so let's force them in.
 s.replace(
     'google/cloud/pubsub_v1/gapic/*er_client.py',
@@ -86,24 +66,6 @@
     \g<0>'''
 )
 
-
-# Stubs are missing
-s.replace(
-    'google/cloud/pubsub_v1/gapic/subscriber_client.py',
-    '^(\s+)if client_info is None:\n',
-    '\g<1>self.iam_policy_stub = (iam_policy_pb2.IAMPolicyStub(channel))'
-    '\g<1>self.subscriber_stub = (pubsub_pb2_grpc.SubscriberStub(channel))\n'
-    '\g<0>'
-)
-
-s.replace(
-    'google/cloud/pubsub_v1/gapic/publisher_client.py',
-    '^(\s+)if client_info is None:\n',
-    '\g<1>self.iam_policy_stub = (iam_policy_pb2.IAMPolicyStub(channel))'
-    '\g<1>self.publisher_stub = (pubsub_pb2_grpc.PublisherStub(channel))\n'
-    '\g<0>'
-)
-
 s.replace(
     'google/cloud/pubsub_v1/gapic/publisher_client.py',
     'import google.api_core.gapic_v1.method\n',


Test patch:
diff --git a/pubsub/tests/unit/pubsub_v1/publisher/test_publisher_client.py b/pubsub/tests/unit/pubsub_v1/publisher/test_publisher_client.py
--- a/pubsub/tests/unit/pubsub_v1/publisher/test_publisher_client.py
+++ b/pubsub/tests/unit/pubsub_v1/publisher/test_publisher_client.py
@@ -46,7 +46,7 @@ def test_init_emulator(monkeypatch):
     #
     # Sadly, there seems to be no good way to do this without poking at
     # the private API of gRPC.
-    channel = client.api.publisher_stub.Publish._channel
+    channel = client.api.transport.publish._channel
     assert channel.target().decode('utf8') == '/foo/bar/'
 
 
diff --git a/pubsub/tests/unit/pubsub_v1/subscriber/test_subscriber_client.py b/pubsub/tests/unit/pubsub_v1/subscriber/test_subscriber_client.py
--- a/pubsub/tests/unit/pubsub_v1/subscriber/test_subscriber_client.py
+++ b/pubsub/tests/unit/pubsub_v1/subscriber/test_subscriber_client.py
@@ -36,7 +36,7 @@ def test_init_emulator(monkeypatch):
     #
     # Sadly, there seems to be no good way to do this without poking at
     # the private API of gRPC.
-    channel = client.api.subscriber_stub.Pull._channel
+    channel = client.api.transport.pull._channel
     assert channel.target().decode('utf8') == '/baz/bacon/'