Merge lp:~oubiwann/txaws/413738-method-name-cleanup into lp:~txawsteam/txaws/trunk

Proposed by Duncan McGreggor on 2009-08-17
Status: Merged
Merge reported by: Duncan McGreggor
Merged at revision: not available
Proposed branch: lp:~oubiwann/txaws/413738-method-name-cleanup
Merge into: lp:~txawsteam/txaws/trunk
Diff against target: None lines
To merge this branch: bzr merge lp:~oubiwann/txaws/413738-method-name-cleanup
Reviewer Review Type Date Requested Status
Robert Collins (community) 2009-08-17 Needs Fixing on 2009-08-18
Jamu Kakar 2009-08-20 Pending
Thomas Herve 2009-08-19 Pending
Review via email: mp+10245@code.launchpad.net
To post a comment you must log in.
Duncan McGreggor (oubiwann) wrote :

This is ready for review. The PEP-8 path was chosen instead of the Twisted coding standard.

Robert Collins (lifeless) wrote :

On Mon, 2009-08-17 at 13:00 +0000, Duncan McGreggor wrote:
>
> +from txaws.util import XML, calculate_md5
> from txaws.credentials import AWSCredentials
> -from txaws.util import XML

PEP8 mandates sorting this:
from txaws.credentials should be the first line.

> +
> +
> +NS = '{http://s3.amazonaws.com/doc/2006-03-01/}'

Rather than NS, perhaps name_space.

> class S3Request(object):
> - def __init__(self, verb, bucket=None, objectName=None, data='',
> - contentType=None, metadata={},
> rootURI='https://s3.amazonaws.com',
> - creds=None):
> +
> + def __init__(
> + self, verb, bucket=None, object_name=None, data='',
> content_type=None,
> + metadata={}, root_uri='https://s3.amazonaws.com',
> creds=None):

I believe PEP-8 allows the style of wrapping that was in use before - I
won't insist either way, but I do fine using as much of the line as
possible nicer. e.g
def __init__(self, verb, bucket, object_name, data,
    content_type, metadata):

> === modified file 'txaws/storage/test/test_client.py'
> --- txaws/storage/test/test_client.py 2009-04-26 08:32:36 +0000
> +++ txaws/storage/test/test_client.py 2009-08-17 12:49:40 +0000
> @@ -4,17 +4,21 @@
>
> from twisted.internet.defer import succeed

c,s,t,u - sorting :) on the import lines below.

> +from txaws.util import calculate_md5
> +from txaws.tests import TXAWSTestCase
> from txaws.credentials import AWSCredentials
> -from txaws.tests import TXAWSTestCase
> -from txaws.storage.client import S3, S3Request, calculateMD5
> +from txaws.storage.client import S3, S3Request
> +
>

> === modified file 'txaws/util.py'
> --- txaws/util.py 2009-04-27 08:53:11 +0000
> +++ txaws/util.py 2009-08-17 12:49:40 +0000
> @@ -6,16 +6,23 @@
>
> __all__ = ['hmac_sha1', 'iso8601time']

and here too.

> +import time
> +import hmac
> +from hashlib import sha1, md5
> from base64 import b64encode
> -from hashlib import sha1
> -import hmac
> -import time
> +

 review needsfixing

review: Needs Fixing
7. By Duncan McGreggor on 2009-08-18

Replaced NS with name_space (lifeless 2).

Duncan McGreggor (oubiwann) wrote :

> On Mon, 2009-08-17 at 13:00 +0000, Duncan McGreggor wrote:
> >
> > +from txaws.util import XML, calculate_md5
> > from txaws.credentials import AWSCredentials
> > -from txaws.util import XML
>
> PEP8 mandates sorting this:
> from txaws.credentials should be the first line.

[1]

So PEP-8 states the following:

      1. standard library imports
      2. related third party imports
      3. local application/library specific imports

Both lines are local application, and there's no further specification on sorting those, is there? Or am I missing something?

> > +
> > +
> > +NS = '{http://s3.amazonaws.com/doc/2006-03-01/}'
>
> Rather than NS, perhaps name_space.

[2]

Good idea -- done.

> > class S3Request(object):
> > - def __init__(self, verb, bucket=None, objectName=None, data='',
> > - contentType=None, metadata={},
> > rootURI='https://s3.amazonaws.com',
> > - creds=None):
> > +
> > + def __init__(
> > + self, verb, bucket=None, object_name=None, data='',
> > content_type=None,
> > + metadata={}, root_uri='https://s3.amazonaws.com',
> > creds=None):
>
> I believe PEP-8 allows the style of wrapping that was in use before - I
> won't insist either way, but I do fine using as much of the line as
> possible nicer. e.g
>
> def __init__(self, verb, bucket, object_name, data,
> content_type, metadata):

[3]

I don't think that's PEP-8, but I may be misreading the PEP. If you take a look at the section that starts with "The preferred way of wrapping long lines..." and the example code below that, they wrap to the point where the parens of the contained code starts, not a 4-space indent (I was actually only made aware of this last year).

I compromised, and re-wrapped like this:

    def __init__(self, verb, bucket, object_name, data,
                 content_type, metadata):

> > === modified file 'txaws/storage/test/test_client.py'
> > --- txaws/storage/test/test_client.py 2009-04-26 08:32:36 +0000
> > +++ txaws/storage/test/test_client.py 2009-08-17 12:49:40 +0000
> > @@ -4,17 +4,21 @@
> >
> > from twisted.internet.defer import succeed
>
> c,s,t,u - sorting :) on the import lines below.
>
> > +from txaws.util import calculate_md5
> > +from txaws.tests import TXAWSTestCase
> > from txaws.credentials import AWSCredentials
> > -from txaws.tests import TXAWSTestCase
> > -from txaws.storage.client import S3, S3Request, calculateMD5
> > +from txaws.storage.client import S3, S3Request
> > +

[4]

Again, same question about the ordering... can you be more specific about what part of PEP-8 I'm missing? Thanks!

> > === modified file 'txaws/util.py'
> > --- txaws/util.py 2009-04-27 08:53:11 +0000
> > +++ txaws/util.py 2009-08-17 12:49:40 +0000
> > @@ -6,16 +6,23 @@
> >
> > __all__ = ['hmac_sha1', 'iso8601time']
>
> and here too.
>
> > +import time
> > +import hmac
> > +from hashlib import sha1, md5
> > from base64 import b64encode
> > -from hashlib import sha1
> > -import hmac
> > -import time
> > +
>
>
> review needsfixing

[5]

Ditto ;-)

8. By Duncan McGreggor on 2009-08-18

Re-wrapped the __init__ method signature in an alternative PEP-8 compliant
manner (lifeless 3).

Robert Collins (lifeless) wrote :

On Tue, 2009-08-18 at 17:48 +0000, Duncan McGreggor wrote:
>
> [1]
>
> So PEP-8 states the following:
>
> 1. standard library imports
> 2. related third party imports
> 3. local application/library specific imports
>
> Both lines are local application, and there's no further specification
> on sorting those, is there? Or am I missing something?

Oh hmm, its a bzr convention. But its very useful, reduces merge
conflicts and makes coffee!

-Rob

9. By Duncan McGreggor on 2009-08-18

Merged from trunk and resolved conflicts.

10. By Duncan McGreggor on 2009-08-18

Renamed NS variable in s3 to name_space.

Duncan McGreggor (oubiwann) wrote :

Hey Rob, you've got your review labeled as "needs fixing" -- is that still the case?

Thanks!

11. By Duncan McGreggor on 2009-08-19

Merged from trunk.

Robert Collins (lifeless) wrote :

Uhm, I'm not sure :)

The only remaining thing was import sorting. I don't think you replied
to my reply on that.

-Rob

Duncan McGreggor (oubiwann) wrote :

On Wed, Aug 19, 2009 at 10:46 PM, Robert
Collins<email address hidden> wrote:
> Uhm, I'm not sure :)
>
> The only remaining thing was import sorting. I don't think you replied
> to my reply on that.

Hrm, well I don't know what you're sorting one... can you explain it?

d

Robert Collins (lifeless) wrote :

On Thu, 2009-08-20 at 02:06 +0000, Duncan McGreggor wrote:
> On Wed, Aug 19, 2009 at 10:46 PM, Robert
> Collins<email address hidden> wrote:
> > Uhm, I'm not sure :)
> >
> > The only remaining thing was import sorting. I don't think you replied
> > to my reply on that.
>
> Hrm, well I don't know what you're sorting one... can you explain it?

the module name, and the item.

from foo import bar
from gam import alpha, beta
from gam.quux import zulu

is well sorted.

Why does sorting matter? It reduces merge conflicts - a lot. Because
when people add the same import they'll do so at the same line, and
different imports will be spread out rather than all at the bottom.

-Rob

Duncan McGreggor (oubiwann) wrote :

On Wed, Aug 19, 2009 at 11:04 PM, Duncan McGreggor<email address hidden> wrote:
> On Wed, Aug 19, 2009 at 10:46 PM, Robert
> Collins<email address hidden> wrote:
>> Uhm, I'm not sure :)
>>
>> The only remaining thing was import sorting. I don't think you replied
>> to my reply on that.
>
> Hrm, well I don't know what you're sorting one... can you explain it?

Er, sorting *on* :-)

d

12. By Duncan McGreggor on 2009-08-20

Sorted import alphabetically (lifeless).

Duncan McGreggor (oubiwann) wrote :

> On Thu, 2009-08-20 at 02:06 +0000, Duncan McGreggor wrote:
> > On Wed, Aug 19, 2009 at 10:46 PM, Robert
> > Collins<email address hidden> wrote:
> > > Uhm, I'm not sure :)
> > >
> > > The only remaining thing was import sorting. I don't think you replied
> > > to my reply on that.
> >
> > Hrm, well I don't know what you're sorting one... can you explain it?
>
> the module name, and the item.
>
> from foo import bar
> from gam import alpha, beta
> from gam.quux import zulu
>
> is well sorted.
>
> Why does sorting matter? It reduces merge conflicts - a lot. Because
> when people add the same import they'll do so at the same line, and
> different imports will be spread out rather than all at the bottom.
>
> -Rob

Awesome. Thanks for the breakdown on that.

I've updated the imports accordingly and pushed.

13. By Duncan McGreggor on 2009-08-20

Renamed storage sub-package's test directory to be consistent with the rest of
txAWS' tests directories.

Duncan McGreggor (oubiwann) wrote :

A quick ping on this branch... I've got dependent branches starting to pile up...

Thanks!

Robert Collins (lifeless) wrote :

in which case,
review +1

Duncan McGreggor (oubiwann) wrote :

> in which case,
> review +1

Thanks!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'txaws/storage/client.py'
2--- txaws/storage/client.py 2009-04-27 08:53:11 +0000
3+++ txaws/storage/client.py 2009-08-17 12:49:40 +0000
4@@ -7,111 +7,107 @@
5 functionality in this wrapper.
6 """
7
8-
9 from hashlib import md5
10 from base64 import b64encode
11
12-
13 from epsilon.extime import Time
14
15 from twisted.web.client import getPage
16 from twisted.web.http import datetimeToString
17
18+from txaws.util import XML, calculate_md5
19 from txaws.credentials import AWSCredentials
20-from txaws.util import XML
21-
22-
23-def calculateMD5(data):
24- digest = md5(data).digest()
25- return b64encode(digest)
26+
27+
28+NS = '{http://s3.amazonaws.com/doc/2006-03-01/}'
29
30
31 class S3Request(object):
32- def __init__(self, verb, bucket=None, objectName=None, data='',
33- contentType=None, metadata={}, rootURI='https://s3.amazonaws.com',
34- creds=None):
35+
36+ def __init__(
37+ self, verb, bucket=None, object_name=None, data='', content_type=None,
38+ metadata={}, root_uri='https://s3.amazonaws.com', creds=None):
39 self.verb = verb
40 self.bucket = bucket
41- self.objectName = objectName
42+ self.object_name = object_name
43 self.data = data
44- self.contentType = contentType
45+ self.content_type = content_type
46 self.metadata = metadata
47- self.rootURI = rootURI
48+ self.root_uri = root_uri
49 self.creds = creds
50 self.date = datetimeToString()
51
52- def getURIPath(self):
53+ def get_uri_path(self):
54 path = '/'
55 if self.bucket is not None:
56 path += self.bucket
57- if self.objectName is not None:
58- path += '/' + self.objectName
59+ if self.object_name is not None:
60+ path += '/' + self.object_name
61 return path
62
63- def getURI(self):
64- return self.rootURI + self.getURIPath()
65+ def get_uri(self):
66+ return self.root_uri + self.get_uri_path()
67
68- def getHeaders(self):
69+ def get_headers(self):
70 headers = {'Content-Length': len(self.data),
71- 'Content-MD5': calculateMD5(self.data),
72+ 'Content-MD5': calculate_md5(self.data),
73 'Date': self.date}
74
75 for key, value in self.metadata.iteritems():
76 headers['x-amz-meta-' + key] = value
77
78- if self.contentType is not None:
79- headers['Content-Type'] = self.contentType
80+ if self.content_type is not None:
81+ headers['Content-Type'] = self.content_type
82
83 if self.creds is not None:
84- signature = self.getSignature(headers)
85+ signature = self.get_signature(headers)
86 headers['Authorization'] = 'AWS %s:%s' % (self.creds.access_key, signature)
87
88 return headers
89
90- def getCanonicalizedResource(self):
91- return self.getURIPath()
92+ def get_canonicalized_resource(self):
93+ return self.get_uri_path()
94
95- def getCanonicalizedAmzHeaders(self, headers):
96+ def get_canonicalized_amz_headers(self, headers):
97 result = ''
98 headers = [(name.lower(), value) for name, value in headers.iteritems() if name.lower().startswith('x-amz-')]
99 headers.sort()
100 return ''.join('%s:%s\n' % (name, value) for name, value in headers)
101
102- def getSignature(self, headers):
103+ def get_signature(self, headers):
104 text = self.verb + '\n'
105 text += headers.get('Content-MD5', '') + '\n'
106 text += headers.get('Content-Type', '') + '\n'
107 text += headers.get('Date', '') + '\n'
108- text += self.getCanonicalizedAmzHeaders(headers)
109- text += self.getCanonicalizedResource()
110+ text += self.get_canonicalized_amz_headers(headers)
111+ text += self.get_canonicalized_resource()
112 return self.creds.sign(text)
113
114 def submit(self):
115- return self.getPage(url=self.getURI(), method=self.verb, postdata=self.data, headers=self.getHeaders())
116+ return self.get_page(url=self.get_uri(), method=self.verb, postdata=self.data, headers=self.get_headers())
117
118- def getPage(self, *a, **kw):
119+ def get_page(self, *a, **kw):
120 return getPage(*a, **kw)
121
122
123-NS = '{http://s3.amazonaws.com/doc/2006-03-01/}'
124-
125 class S3(object):
126- rootURI = 'https://s3.amazonaws.com/'
127- requestFactory = S3Request
128+
129+ root_uri = 'https://s3.amazonaws.com/'
130+ request_factory = S3Request
131
132 def __init__(self, creds):
133 self.creds = creds
134
135- def makeRequest(self, *a, **kw):
136+ def make_request(self, *a, **kw):
137 """
138 Create a request with the arguments passed in.
139
140- This uses the requestFactory attribute, adding the credentials to the
141+ This uses the request_factory attribute, adding the credentials to the
142 arguments passed in.
143 """
144- return self.requestFactory(creds=self.creds, *a, **kw)
145+ return self.request_factory(creds=self.creds, *a, **kw)
146
147- def _parseBucketList(self, response):
148+ def _parse_bucket_list(self, response):
149 """
150 Parse XML bucket list response.
151 """
152@@ -120,57 +116,57 @@
153 yield {'name': bucket.findtext(NS + 'Name'),
154 'created': Time.fromISO8601TimeAndDate(bucket.findtext(NS + 'CreationDate'))}
155
156- def listBuckets(self):
157+ def list_buckets(self):
158 """
159 List all buckets.
160
161 Returns a list of all the buckets owned by the authenticated sender of
162 the request.
163 """
164- return self.makeRequest('GET').submit().addCallback(self._parseBucketList)
165+ return self.make_request('GET').submit().addCallback(self._parse_bucket_list)
166
167- def createBucket(self, bucket):
168+ def create_bucket(self, bucket):
169 """
170 Create a new bucket.
171 """
172- return self.makeRequest('PUT', bucket).submit()
173+ return self.make_request('PUT', bucket).submit()
174
175- def deleteBucket(self, bucket):
176+ def delete_bucket(self, bucket):
177 """
178 Delete a bucket.
179
180 The bucket must be empty before it can be deleted.
181 """
182- return self.makeRequest('DELETE', bucket).submit()
183+ return self.make_request('DELETE', bucket).submit()
184
185- def putObject(self, bucket, objectName, data, contentType=None, metadata={}):
186+ def put_object(self, bucket, object_name, data, content_type=None, metadata={}):
187 """
188 Put an object in a bucket.
189
190 Any existing object of the same name will be replaced.
191 """
192- return self.makeRequest('PUT', bucket, objectName, data, contentType, metadata).submit()
193+ return self.make_request('PUT', bucket, object_name, data, content_type, metadata).submit()
194
195- def getObject(self, bucket, objectName):
196+ def get_object(self, bucket, object_name):
197 """
198 Get an object from a bucket.
199 """
200- return self.makeRequest('GET', bucket, objectName).submit()
201+ return self.make_request('GET', bucket, object_name).submit()
202
203- def headObject(self, bucket, objectName):
204+ def head_object(self, bucket, object_name):
205 """
206 Retrieve object metadata only.
207
208- This is like getObject, but the object's content is not retrieved.
209+ This is like get_object, but the object's content is not retrieved.
210 Currently the metadata is not returned to the caller either, so this
211 method is mostly useless, and only provided for completeness.
212 """
213- return self.makeRequest('HEAD', bucket, objectName).submit()
214+ return self.make_request('HEAD', bucket, object_name).submit()
215
216- def deleteObject(self, bucket, objectName):
217+ def delete_object(self, bucket, object_name):
218 """
219 Delete an object from a bucket.
220
221 Once deleted, there is no method to restore or undelete an object.
222 """
223- return self.makeRequest('DELETE', bucket, objectName).submit()
224+ return self.make_request('DELETE', bucket, object_name).submit()
225
226=== modified file 'txaws/storage/test/test_client.py'
227--- txaws/storage/test/test_client.py 2009-04-26 08:32:36 +0000
228+++ txaws/storage/test/test_client.py 2009-08-17 12:49:40 +0000
229@@ -4,17 +4,21 @@
230
231 from twisted.internet.defer import succeed
232
233+from txaws.util import calculate_md5
234+from txaws.tests import TXAWSTestCase
235 from txaws.credentials import AWSCredentials
236-from txaws.tests import TXAWSTestCase
237-from txaws.storage.client import S3, S3Request, calculateMD5
238+from txaws.storage.client import S3, S3Request
239+
240
241 class StubbedS3Request(S3Request):
242- def getPage(self, url, method, postdata, headers):
243+
244+ def get_page(self, url, method, postdata, headers):
245 self.getPageArgs = (url, method, postdata, headers)
246 return succeed('')
247
248
249 class RequestTests(TXAWSTestCase):
250+
251 creds = AWSCredentials(access_key='0PN5J17HBGZHT7JJ3X82',
252 secret_key='uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o')
253
254@@ -25,10 +29,10 @@
255 DATA = 'objectData'
256 DIGEST = 'zhdB6gwvocWv/ourYUWMxA=='
257
258- request = S3Request('PUT', 'somebucket', 'object/name/here', DATA, contentType='text/plain', metadata={'foo': 'bar'})
259+ request = S3Request('PUT', 'somebucket', 'object/name/here', DATA, content_type='text/plain', metadata={'foo': 'bar'})
260 self.assertEqual(request.verb, 'PUT')
261- self.assertEqual(request.getURI(), 'https://s3.amazonaws.com/somebucket/object/name/here')
262- headers = request.getHeaders()
263+ self.assertEqual(request.get_uri(), 'https://s3.amazonaws.com/somebucket/object/name/here')
264+ headers = request.get_headers()
265 self.assertNotEqual(headers.pop('Date'), '')
266 self.assertEqual(headers,
267 {'Content-Type': 'text/plain',
268@@ -45,8 +49,8 @@
269
270 request = S3Request('GET', 'somebucket')
271 self.assertEqual(request.verb, 'GET')
272- self.assertEqual(request.getURI(), 'https://s3.amazonaws.com/somebucket')
273- headers = request.getHeaders()
274+ self.assertEqual(request.get_uri(), 'https://s3.amazonaws.com/somebucket')
275+ headers = request.get_headers()
276 self.assertNotEqual(headers.pop('Date'), '')
277 self.assertEqual(headers,
278 {'Content-Length': 0,
279@@ -63,10 +67,10 @@
280 self.assertEqual(result, '')
281
282 url, method, postdata, headers = request.getPageArgs
283- self.assertEqual(url, request.getURI())
284+ self.assertEqual(url, request.get_uri())
285 self.assertEqual(method, request.verb)
286 self.assertEqual(postdata, request.data)
287- self.assertEqual(headers, request.getHeaders())
288+ self.assertEqual(headers, request.get_headers())
289
290 return request.submit().addCallback(_postCheck)
291
292@@ -74,7 +78,7 @@
293 req = S3Request('GET', creds=self.creds)
294 req.date = 'Wed, 28 Mar 2007 01:29:59 +0000'
295
296- headers = req.getHeaders()
297+ headers = req.get_headers()
298 self.assertEqual(headers['Authorization'], 'AWS 0PN5J17HBGZHT7JJ3X82:jF7L3z/FTV47vagZzhKupJ9oNig=')
299
300
301@@ -102,13 +106,13 @@
302 """
303 Testable version of S3.
304
305- This subclass stubs requestFactory to use InertRequest, making it easy to
306+ This subclass stubs request_factory to use InertRequest, making it easy to
307 assert things about the requests that are created in response to various
308 operations.
309 """
310 response = None
311
312- def requestFactory(self, *a, **kw):
313+ def request_factory(self, *a, **kw):
314 req = InertRequest(response=self.response, *a, **kw)
315 self._lastRequest = req
316 return req
317@@ -143,9 +147,9 @@
318 self.creds = AWSCredentials(access_key='accessKey', secret_key='secretKey')
319 self.s3 = TestableS3(creds=self.creds)
320
321- def test_makeRequest(self):
322+ def test_make_request(self):
323 """
324- Test that makeRequest passes in the service credentials.
325+ Test that make_request passes in the service credentials.
326 """
327 marker = object()
328
329@@ -153,79 +157,79 @@
330 self.assertEqual(kw['creds'], self.creds)
331 return marker
332
333- self.s3.requestFactory = _cb
334- self.assertIdentical(self.s3.makeRequest('GET'), marker)
335+ self.s3.request_factory = _cb
336+ self.assertIdentical(self.s3.make_request('GET'), marker)
337
338- def test_listBuckets(self):
339+ def test_list_buckets(self):
340 self.s3.response = samples['ListAllMyBucketsResult']
341- d = self.s3.listBuckets()
342+ d = self.s3.list_buckets()
343
344 req = self.s3._lastRequest
345 self.assertTrue(req.submitted)
346 self.assertEqual(req.verb, 'GET')
347 self.assertEqual(req.bucket, None)
348- self.assertEqual(req.objectName, None)
349+ self.assertEqual(req.object_name, None)
350
351- def _checkResult(buckets):
352+ def _check_result(buckets):
353 self.assertEqual(list(buckets),
354 [{'name': u'quotes',
355 'created': Time.fromDatetime(datetime(2006, 2, 3, 16, 45, 9))},
356 {'name': u'samples',
357 'created': Time.fromDatetime(datetime(2006, 2, 3, 16, 41, 58))}])
358- return d.addCallback(_checkResult)
359+ return d.addCallback(_check_result)
360
361- def test_createBucket(self):
362- self.s3.createBucket('foo')
363+ def test_create_bucket(self):
364+ self.s3.create_bucket('foo')
365 req = self.s3._lastRequest
366 self.assertTrue(req.submitted)
367 self.assertEqual(req.verb, 'PUT')
368 self.assertEqual(req.bucket, 'foo')
369- self.assertEqual(req.objectName, None)
370+ self.assertEqual(req.object_name, None)
371
372- def test_deleteBucket(self):
373- self.s3.deleteBucket('foo')
374+ def test_delete_bucket(self):
375+ self.s3.delete_bucket('foo')
376 req = self.s3._lastRequest
377 self.assertTrue(req.submitted)
378 self.assertEqual(req.verb, 'DELETE')
379 self.assertEqual(req.bucket, 'foo')
380- self.assertEqual(req.objectName, None)
381+ self.assertEqual(req.object_name, None)
382
383- def test_putObject(self):
384- self.s3.putObject('foobucket', 'foo', 'data', 'text/plain', {'foo': 'bar'})
385+ def test_put_object(self):
386+ self.s3.put_object('foobucket', 'foo', 'data', 'text/plain', {'foo': 'bar'})
387 req = self.s3._lastRequest
388 self.assertTrue(req.submitted)
389 self.assertEqual(req.verb, 'PUT')
390 self.assertEqual(req.bucket, 'foobucket')
391- self.assertEqual(req.objectName, 'foo')
392+ self.assertEqual(req.object_name, 'foo')
393 self.assertEqual(req.data, 'data')
394- self.assertEqual(req.contentType, 'text/plain')
395+ self.assertEqual(req.content_type, 'text/plain')
396 self.assertEqual(req.metadata, {'foo': 'bar'})
397
398- def test_getObject(self):
399- self.s3.getObject('foobucket', 'foo')
400+ def test_get_object(self):
401+ self.s3.get_object('foobucket', 'foo')
402 req = self.s3._lastRequest
403 self.assertTrue(req.submitted)
404 self.assertEqual(req.verb, 'GET')
405 self.assertEqual(req.bucket, 'foobucket')
406- self.assertEqual(req.objectName, 'foo')
407+ self.assertEqual(req.object_name, 'foo')
408
409- def test_headObject(self):
410- self.s3.headObject('foobucket', 'foo')
411+ def test_head_object(self):
412+ self.s3.head_object('foobucket', 'foo')
413 req = self.s3._lastRequest
414 self.assertTrue(req.submitted)
415 self.assertEqual(req.verb, 'HEAD')
416 self.assertEqual(req.bucket, 'foobucket')
417- self.assertEqual(req.objectName, 'foo')
418+ self.assertEqual(req.object_name, 'foo')
419
420- def test_deleteObject(self):
421- self.s3.deleteObject('foobucket', 'foo')
422+ def test_delete_object(self):
423+ self.s3.delete_object('foobucket', 'foo')
424 req = self.s3._lastRequest
425 self.assertTrue(req.submitted)
426 self.assertEqual(req.verb, 'DELETE')
427 self.assertEqual(req.bucket, 'foobucket')
428- self.assertEqual(req.objectName, 'foo')
429+ self.assertEqual(req.object_name, 'foo')
430
431
432 class MiscellaneousTests(TXAWSTestCase):
433 def test_contentMD5(self):
434- self.assertEqual(calculateMD5('somedata'), 'rvr3UC1SmUw7AZV2NqPN0g==')
435+ self.assertEqual(calculate_md5('somedata'), 'rvr3UC1SmUw7AZV2NqPN0g==')
436
437=== modified file 'txaws/util.py'
438--- txaws/util.py 2009-04-27 08:53:11 +0000
439+++ txaws/util.py 2009-08-17 12:49:40 +0000
440@@ -6,16 +6,23 @@
441
442 __all__ = ['hmac_sha1', 'iso8601time']
443
444+import time
445+import hmac
446+from hashlib import sha1, md5
447 from base64 import b64encode
448-from hashlib import sha1
449-import hmac
450-import time
451+
452 # Import XML from somwhere; here in one place to prevent duplication.
453 try:
454 from xml.etree.ElementTree import XML
455 except ImportError:
456 from elementtree.ElementTree import XML
457
458+
459+def calculate_md5(data):
460+ digest = md5(data).digest()
461+ return b64encode(digest)
462+
463+
464 def hmac_sha1(secret, data):
465 digest = hmac.new(secret, data, sha1).digest()
466 return b64encode(digest)

Subscribers

People subscribed via source and target branches