Skip to content

Commit fa2ff2b

Browse files
committed
Deferring implicit connection behavior from storage.api to Bucket.
1 parent e25034d commit fa2ff2b

File tree

6 files changed

+92
-30
lines changed

6 files changed

+92
-30
lines changed

gcloud/storage/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def set_default_bucket(bucket=None):
8383
bucket_name = os.getenv(_BUCKET_ENV_VAR_NAME)
8484
connection = get_default_connection()
8585

86-
if bucket_name is not None and connection is not None:
86+
if bucket_name is not None:
8787
bucket = Bucket(bucket_name, connection=connection)
8888

8989
if bucket is not None:

gcloud/storage/api.py

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,11 @@ def lookup_bucket(bucket_name, connection=None):
4646
:type connection: :class:`gcloud.storage.connection.Connection` or
4747
``NoneType``
4848
:param connection: Optional. The connection to use when sending requests.
49-
If not provided, falls back to default.
49+
If not provided, Bucket() will fall back to default.
5050
5151
:rtype: :class:`gcloud.storage.bucket.Bucket`
5252
:returns: The bucket matching the name provided or None if not found.
5353
"""
54-
if connection is None:
55-
connection = get_default_connection()
56-
5754
try:
5855
return get_bucket(bucket_name, connection=connection)
5956
except NotFound:
@@ -116,15 +113,11 @@ def get_bucket(bucket_name, connection=None):
116113
:type connection: :class:`gcloud.storage.connection.Connection` or
117114
``NoneType``
118115
:param connection: Optional. The connection to use when sending requests.
119-
If not provided, falls back to default.
116+
If not provided, Bucket() will fall back to default.
120117
121118
:rtype: :class:`gcloud.storage.bucket.Bucket`
122119
:returns: The bucket matching the name provided.
123-
:raises: :class:`gcloud.exceptions.NotFound`
124120
"""
125-
if connection is None:
126-
connection = get_default_connection()
127-
128121
bucket = Bucket(bucket_name, connection=connection)
129122
bucket._reload_properties()
130123
return bucket
@@ -143,6 +136,9 @@ def create_bucket(bucket_name, project=None, connection=None):
143136
144137
This implements "storage.buckets.insert".
145138
139+
If the bucket already exists, will raise
140+
:class:`gcloud.exceptions.Conflict`.
141+
146142
:type project: string
147143
:param project: Optional. The project to use when creating bucket.
148144
If not provided, falls back to default.
@@ -153,25 +149,13 @@ def create_bucket(bucket_name, project=None, connection=None):
153149
:type connection: :class:`gcloud.storage.connection.Connection` or
154150
``NoneType``
155151
:param connection: Optional. The connection to use when sending requests.
156-
If not provided, falls back to default.
152+
If not provided, Bucket() will fall back to default.
157153
158154
:rtype: :class:`gcloud.storage.bucket.Bucket`
159155
:returns: The newly created bucket.
160-
:raises: :class:`gcloud.exceptions.Conflict` if
161-
there is a confict (bucket already exists, invalid name, etc.)
162156
"""
163-
if connection is None:
164-
connection = get_default_connection()
165-
if project is None:
166-
project = get_default_project()
167-
168-
query_params = {'project': project}
169-
response = connection.api_request(method='POST', path='/b',
170-
query_params=query_params,
171-
data={'name': bucket_name})
172-
name = response.get('name')
173-
bucket = Bucket(name, connection=connection)
174-
bucket._properties = response
157+
bucket = Bucket(bucket_name, connection=connection)
158+
bucket.create(project)
175159
return bucket
176160

177161

gcloud/storage/bucket.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import os
3737
import six
3838

39+
from gcloud._helpers import get_default_project
3940
from gcloud.exceptions import NotFound
4041
from gcloud.storage._helpers import _PropertyMixin
4142
from gcloud.storage._helpers import _scalar_property
@@ -127,6 +128,34 @@ def exists(self):
127128
except NotFound:
128129
return False
129130

131+
def create(self, project=None):
132+
"""Creates current bucket.
133+
134+
If the bucket already exists, will raise
135+
:class:`gcloud.exceptions.Conflict`.
136+
137+
This implements "storage.buckets.insert".
138+
139+
:type project: string
140+
:param project: Optional. The project to use when creating bucket.
141+
If not provided, falls back to default.
142+
143+
:rtype: :class:`gcloud.storage.bucket.Bucket`
144+
:returns: The newly created bucket.
145+
:raises: :class:`EnvironmentError` if the project is not given and
146+
can't be inferred.
147+
"""
148+
if project is None:
149+
project = get_default_project()
150+
if project is None:
151+
raise EnvironmentError('Project could not be inferred '
152+
'from environment.')
153+
154+
query_params = {'project': project}
155+
self._properties = self.connection.api_request(
156+
method='POST', path='/b', query_params=query_params,
157+
data={'name': self.name})
158+
130159
@property
131160
def acl(self):
132161
"""Create our ACL on demand."""

gcloud/storage/test_api.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,15 @@ def _lookup_bucket_hit_helper(self, use_default=False):
6262
if use_default:
6363
with _monkey_defaults(connection=conn):
6464
bucket = self._callFUT(BLOB_NAME)
65+
# In the default case, the bucket never has a connection
66+
# bound to it.
67+
self.assertTrue(bucket._connection is None)
6568
else:
6669
bucket = self._callFUT(BLOB_NAME, connection=conn)
70+
# In the explicit case, the bucket has a connection bound to it.
71+
self.assertTrue(bucket._connection is conn)
6772

6873
self.assertTrue(isinstance(bucket, Bucket))
69-
self.assertTrue(bucket.connection is conn)
7074
self.assertEqual(bucket.name, BLOB_NAME)
7175
self.assertEqual(http._called_with['method'], 'GET')
7276
self.assertEqual(http._called_with['uri'], URI)
@@ -187,11 +191,15 @@ def _get_bucket_hit_helper(self, use_default=False):
187191
if use_default:
188192
with _monkey_defaults(connection=conn):
189193
bucket = self._callFUT(BLOB_NAME)
194+
# In the default case, the bucket never has a connection
195+
# bound to it.
196+
self.assertTrue(bucket._connection is None)
190197
else:
191198
bucket = self._callFUT(BLOB_NAME, connection=conn)
199+
# In the explicit case, the bucket has a connection bound to it.
200+
self.assertTrue(bucket._connection is conn)
192201

193202
self.assertTrue(isinstance(bucket, Bucket))
194-
self.assertTrue(bucket.connection is conn)
195203
self.assertEqual(bucket.name, BLOB_NAME)
196204
self.assertEqual(http._called_with['method'], 'GET')
197205
self.assertEqual(http._called_with['uri'], URI)
@@ -232,11 +240,15 @@ def _create_bucket_success_helper(self, project, use_default=False):
232240
with _base_monkey_defaults(project=project):
233241
with _monkey_defaults(connection=conn):
234242
bucket = self._callFUT(BLOB_NAME)
243+
# In the default case, the bucket never has a connection
244+
# bound to it.
245+
self.assertTrue(bucket._connection is None)
235246
else:
236247
bucket = self._callFUT(BLOB_NAME, project=project, connection=conn)
248+
# In the explicit case, the bucket has a connection bound to it.
249+
self.assertTrue(bucket._connection is conn)
237250

238251
self.assertTrue(isinstance(bucket, Bucket))
239-
self.assertTrue(bucket.connection is conn)
240252
self.assertEqual(bucket.name, BLOB_NAME)
241253
self.assertEqual(http._called_with['method'], 'POST')
242254
self.assertEqual(http._called_with['uri'], URI)

gcloud/storage/test_bucket.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,43 @@ def api_request(cls, *args, **kwargs):
182182
expected_cw = [((), expected_called_kwargs)]
183183
self.assertEqual(_FakeConnection._called_with, expected_cw)
184184

185+
def test_create_no_project(self):
186+
from gcloud._testing import _monkey_defaults
187+
BUCKET_NAME = 'bucket-name'
188+
bucket = self._makeOne(BUCKET_NAME)
189+
with _monkey_defaults(project=None):
190+
self.assertRaises(EnvironmentError, bucket.create)
191+
192+
def test_create_hit_explicit_project(self):
193+
BUCKET_NAME = 'bucket-name'
194+
DATA = {'name': BUCKET_NAME}
195+
connection = _Connection(DATA)
196+
PROJECT = 'PROJECT'
197+
bucket = self._makeOne(BUCKET_NAME, connection=connection)
198+
bucket.create(PROJECT)
199+
200+
kw, = connection._requested
201+
self.assertEqual(kw['method'], 'POST')
202+
self.assertEqual(kw['path'], '/b')
203+
self.assertEqual(kw['query_params'], {'project': PROJECT})
204+
self.assertEqual(kw['data'], DATA)
205+
206+
def test_create_hit_implicit_project(self):
207+
from gcloud._testing import _monkey_defaults
208+
BUCKET_NAME = 'bucket-name'
209+
DATA = {'name': BUCKET_NAME}
210+
connection = _Connection(DATA)
211+
PROJECT = 'PROJECT'
212+
bucket = self._makeOne(BUCKET_NAME, connection=connection)
213+
with _monkey_defaults(project=PROJECT):
214+
bucket.create()
215+
216+
kw, = connection._requested
217+
self.assertEqual(kw['method'], 'POST')
218+
self.assertEqual(kw['path'], '/b')
219+
self.assertEqual(kw['query_params'], {'project': PROJECT})
220+
self.assertEqual(kw['data'], DATA)
221+
185222
def test_acl_property(self):
186223
from gcloud.storage.acl import BucketACL
187224
bucket = self._makeOne()

regression/storage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ def setUp(self):
5151
self.case_buckets_to_delete = []
5252

5353
def tearDown(self):
54-
with storage.Batch() as batch:
54+
with storage.Batch():
5555
for bucket_name in self.case_buckets_to_delete:
56-
storage.Bucket(bucket_name, connection=batch).delete()
56+
storage.Bucket(bucket_name).delete()
5757

5858
def test_create_bucket(self):
5959
new_bucket_name = 'a-new-bucket'

0 commit comments

Comments
 (0)