14
14
except :
15
15
__version__ = 'unknown'
16
16
17
+ import collections
17
18
import copy
18
19
import hashlib
19
- import httplib
20
20
import json
21
21
import os .path
22
22
import re
23
23
import socket
24
24
import time
25
- import urllib
26
- import urlparse
27
25
28
- from collections import defaultdict
26
+ from ._compat import (
27
+ MutableMapping , iteritems , string_types , httplib , urlparse , urlencode ,
28
+ )
29
+
29
30
30
31
__all__ = ['Phabricator' ]
31
32
33
+
32
34
# Default phabricator interfaces
33
35
INTERFACES = json .loads (open (os .path .join (os .path .dirname (__file__ ), 'interfaces.json' ), 'r' ).read ())
34
36
79
81
'pair' : tuple ,
80
82
81
83
# str types
82
- 'str' : basestring ,
83
- 'string' : basestring ,
84
- 'phid' : basestring ,
85
- 'guids' : basestring ,
86
- 'type' : basestring ,
84
+ 'str' : string_types ,
85
+ 'string' : string_types ,
86
+ 'phid' : string_types ,
87
+ 'guids' : string_types ,
88
+ 'type' : string_types ,
87
89
}
88
90
89
91
STR_RE = re .compile (r'([a-zA-Z_]+)' )
@@ -108,9 +110,9 @@ def map_param_type(param_type):
108
110
sub_match = STR_RE .match (sub_type )
109
111
sub_type = sub_match .group (0 ).lower ()
110
112
111
- return [PARAM_TYPE_MAP .setdefault (sub_type , basestring )]
113
+ return [PARAM_TYPE_MAP .setdefault (sub_type , string_types )]
112
114
113
- return PARAM_TYPE_MAP .setdefault (main_type , basestring )
115
+ return PARAM_TYPE_MAP .setdefault (main_type , string_types )
114
116
115
117
116
118
def parse_interfaces (interfaces ):
@@ -119,9 +121,9 @@ def parse_interfaces(interfaces):
119
121
This performs the logic of parsing the non-standard params dict
120
122
and then returning a dict Resource can understand
121
123
"""
122
- parsed_interfaces = defaultdict (dict )
124
+ parsed_interfaces = collections . defaultdict (dict )
123
125
124
- for m , d in interfaces . iteritems ():
126
+ for m , d in iteritems (interfaces ):
125
127
app , func = m .split ('.' , 1 )
126
128
127
129
method = parsed_interfaces [app ][func ] = {}
@@ -133,7 +135,7 @@ def parse_interfaces(interfaces):
133
135
method ['optional' ] = {}
134
136
method ['required' ] = {}
135
137
136
- for name , type_info in dict (d ['params' ]). iteritems ( ):
138
+ for name , type_info in iteritems ( dict (d ['params' ])):
137
139
# Usually in the format: <optionality> <param_type>
138
140
info_pieces = type_info .split (' ' , 1 )
139
141
@@ -176,42 +178,29 @@ class InvalidAccessToken(APIError):
176
178
pass
177
179
178
180
179
- class Result (object ):
181
+ class Result (MutableMapping ):
180
182
def __init__ (self , response ):
181
183
self .response = response
182
184
183
- def __repr__ (self ):
184
- return '<%s: %s>' % (self .__class__ .__name__ , repr (self .response ))
185
-
186
- def __iter__ (self ):
187
- for r in self .response :
188
- yield r
189
-
190
185
def __getitem__ (self , key ):
191
186
return self .response [key ]
192
187
193
- def __getattr__ (self , key ):
194
- return self .response [key ]
188
+ __getattr__ = __getitem__
189
+
190
+ def __setitem__ (self , key , value ):
191
+ self .response [key ] = value
195
192
196
- def __getstate__ (self ):
197
- return self .response
193
+ def __delitem__ (self , key ):
194
+ del self .response [ key ]
198
195
199
- def __setstate__ (self , state ):
200
- self .response = state
196
+ def __iter__ (self ):
197
+ return iter ( self .response )
201
198
202
199
def __len__ (self ):
203
200
return len (self .response .keys ())
204
201
205
- def keys (self ):
206
- return self .response .keys ()
207
-
208
- def iteritems (self ):
209
- for k , v in self .response .iteritems ():
210
- yield k , v
211
-
212
- def itervalues (self ):
213
- for v in self .response .itervalues ():
214
- yield v
202
+ def __repr__ (self ):
203
+ return '<%s: %s>' % (type (self ).__name__ , repr (self .response ))
215
204
216
205
217
206
class Resource (object ):
@@ -240,17 +229,17 @@ def validate_kwarg(key, target):
240
229
# Always allow list
241
230
if isinstance (key , list ):
242
231
return all ([validate_kwarg (x , target [0 ]) for x in key ])
243
- return isinstance (key , target )
244
-
245
- for k in resource .get ('required' , [] ):
246
- if k not in [x .split (':' )[0 ] for x in kwargs .keys ()]:
247
- raise ValueError ('Missing required argument: %s' % k )
248
- if isinstance (kwargs .get (k ), list ) and not isinstance (resource [ 'required' ][ k ] , list ):
249
- raise ValueError ('Wrong argument type: %s is not a list' % k )
250
- elif not validate_kwarg (kwargs .get (k ), resource [ 'required' ][ k ] ):
251
- if isinstance (resource [ 'required' ][ k ] , list ):
252
- raise ValueError ('Wrong arguemnt type: %s is not a list of %ss' % (k , resource [ 'required' ][ k ] [0 ]))
253
- raise ValueError ('Wrong arguemnt type: %s is not a %s' % (k , resource [ 'required' ][ k ] ))
232
+ return isinstance (key , tuple ( target ) if isinstance ( target , list ) else target )
233
+
234
+ for key , val in resource .get ('required' , {}). items ( ):
235
+ if key not in [x .split (':' )[0 ] for x in kwargs .keys ()]:
236
+ raise ValueError ('Missing required argument: %s' % key )
237
+ if isinstance (kwargs .get (key ), list ) and not isinstance (val , list ):
238
+ raise ValueError ('Wrong argument type: %s is not a list' % key )
239
+ elif not validate_kwarg (kwargs .get (key ), val ):
240
+ if isinstance (val , list ):
241
+ raise ValueError ('Wrong argument type: %s is not a list of %ss' % (key , val [0 ]))
242
+ raise ValueError ('Wrong argument type: %s is not a %s' % (key , val ))
254
243
255
244
conduit = self .api .conduit
256
245
@@ -280,7 +269,7 @@ def validate_kwarg(key, target):
280
269
'Content-Type' : 'application/x-www-form-urlencoded'
281
270
}
282
271
283
- body = urllib . urlencode ({
272
+ body = urlencode ({
284
273
"params" : json .dumps (kwargs ),
285
274
"output" : self .api .response_format
286
275
})
@@ -355,7 +344,8 @@ def connect(self):
355
344
}
356
345
357
346
def generate_hash (self , token ):
358
- return hashlib .sha1 (token + self .api .certificate ).hexdigest ()
347
+ source_string = (token + self .api .certificate ).encode ('utf-8' )
348
+ return hashlib .sha1 (source_string ).hexdigest ()
359
349
360
350
def update_interfaces (self ):
361
351
query = Resource (api = self , method = 'conduit' , endpoint = 'query' )
0 commit comments