Commits

Anonymous committed cb68b7b

unicode & ... seem to be fixed now. While I'm here remove useless
functions from django. We don't need them.

Comments (0)

Files changed (7)

restclient/rest.py

 
 from restclient.transport import getDefaultHTTPTransport, \
 HTTPTransportBase, TransportError
-from restclient.utils import force_unicode, smart_str
+from restclient.utils import to_bytestring
 
 __all__ = ['Resource', 'RestClient', 'ResourceNotFound', \
         'Unauthorized', 'RequestFailed', 'ResourceError',
 
     """
     def __new__(cls, s, http_code, response):
-        self = unicode.__new__(cls, force_unicode(s))
+        if not isinstance(s, unicode):
+            s = s.decode('utf-8')
+        self = unicode.__new__(cls, s)
         self.http_code = http_code
         self.response = response
         return self
         elif body is not None:
             if not isinstance(body, unicode):            
                 is_unicode = False
-            body = smart_str(body)
+            body = to_bytestring(body)
 
         try:
             resp, data = self.transport.request(self.make_uri(uri, path, **params), 

restclient/transport.py

 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #
+
+import codecs
 import StringIO
 import httplib
 
 import sys
 
 import restclient
-from restclient.utils import smart_str, iri2uri
+from restclient.utils import to_bytestring, iri2uri
 
 try:
     import httplib2
             header = StringIO.StringIO()
             c.setopt(pycurl.WRITEFUNCTION, data.write)
             c.setopt(pycurl.HEADERFUNCTION, header.write)
-            c.setopt(pycurl.URL, smart_str(url))
+            c.setopt(pycurl.URL, to_bytestring(url))
             c.setopt(pycurl.FOLLOWLOCATION, 1)
             c.setopt(pycurl.MAXREDIRS, 5)
             c.setopt(pycurl.NOSIGNAL, 1)
                         0))
                     content = body
                 else:
-                    if isinstance(body, unicode):
-                        body = smart_str(body)
                     content = StringIO.StringIO(body)
                     if 'Content-Length' in headers:
                         del headers['Content-Length']
                     content_length = len(body)
 
+                reader = codecs.getreader('string_escape')(content)
+
                 if method in ('POST'):
                     c.setopt(pycurl.POSTFIELDSIZE, content_length)
                 else:
                     c.setopt(pycurl.INFILESIZE, content_length)
-                c.setopt(pycurl.READFUNCTION, content.read)
+                c.setopt(pycurl.READFUNCTION, reader.read)
             
             if headers:
                 _normalize_headers(headers)

restclient/utils.py

 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 # DEALINGS IN THE SOFTWARE.
 #
-# smart_str and force_unicode code taken from django project under the following
-# license :
-# BSD License
-#
-# Copyright (c) 2009 Django Software Foundation and individual contributors.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-#    1. Redistributions of source code must retain the above copyright notice, 
-#       this list of conditions and the following disclaimer.
-#    
-#    2. Redistributions in binary form must reproduce the above copyright 
-#       notice, this list of conditions and the following disclaimer in the
-#       documentation and/or other materials provided with the distribution.
-#
-#    3. Neither the name of Django nor the names of its contributors may be used
-#       to endorse or promote products derived from this software without
-#       specific prior written permission.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 """
 iri2uri
 
 import urlparse
 
 
-def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
-    """
-    Returns a bytestring version of 's', encoded as specified in 'encoding'.
+def to_bytestring(s):
+    if not isinstance(s, basestring):
+        raise TypeError("value should be a str or unicode")
 
-    If strings_only is True, don't convert (some) non-string-like objects.
-    """
-    if strings_only and isinstance(s, (types.NoneType, int)):
-        return s
-   
-    if not isinstance(s, basestring):
-        try:
-            return str(s)
-        except UnicodeEncodeError:
-            if isinstance(s, Exception):
-                # An Exception subclass containing non-ASCII data that doesn't
-                # know how to print itself properly. We shouldn't raise a
-                # further exception.
-                return ' '.join([smart_str(arg, encoding, strings_only,
-                        errors) for arg in s])
-            return unicode(s).encode(encoding, errors)
-    elif isinstance(s, unicode):
-        return s.encode(encoding, errors)
-    elif s and encoding != 'utf-8':
-        return s.decode('utf-8', errors).encode(encoding, errors)
-    else:
-        return s
-
-def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
-    """
-    Similar to smart_unicode, except that lazy instances are resolved to
-    strings, rather than kept as lazy objects.
-
-    If strings_only is True, don't convert (some) non-string-like objects.
-    """
-    if strings_only and isinstance(s, (types.NoneType, int, long, datetime.datetime, datetime.date, datetime.time, float)):
-        return s
-    try:
-        if not isinstance(s, basestring,):
-            if hasattr(s, '__unicode__'):
-                s = unicode(s)
-            else:
-                try:
-                    s = unicode(str(s), encoding, errors)
-                except UnicodeEncodeError:
-                    if not isinstance(s, Exception):
-                        raise
-                    # If we get to here, the caller has passed in an Exception
-                    # subclass populated with non-ASCII data without special
-                    # handling to display as a string. We need to handle this
-                    # without raising a further exception. We do an
-                    # approximation to what the Exception's standard str()
-                    # output should be.
-                    s = ' '.join([force_unicode(arg, encoding, strings_only,
-                            errors) for arg in s])
-        elif not isinstance(s, unicode):
-            # Note: We use .decode() here, instead of unicode(s, encoding,
-            # errors), so that if s is a SafeString, it ends up being a
-            # SafeUnicode at the end.
-            s = s.decode(encoding, errors)
-    except UnicodeDecodeError, e:
-        raise e
+    if isinstance(s, unicode):
+        return s.encode('utf-8')
     return s
 
 # Convert an IRI to a URI following the rules in RFC 3987
 
 setup(
     name = 'py-restclient',
-    version = '1.1.6',
+    version = '1.1.7',
     description = 'Python REST client',
     long_description = \
 """A simple REST client for Python, inspired by the microframework (Camping, Sinatra) style of specifying actions: get, put, post, delete.""",

tests/_server_test.py

 import threading
 import unittest
 import urlparse
-
-from restclient.transport import smart_str
+import urllib
+from restclient.utils import to_bytestring
 
 HOST = socket.getfqdn('127.0.0.1')
 PORT = (os.getpid() % 31000) + 1024
         BaseHTTPRequestHandler.__init__(self, request, client_address, server)
         
     def do_GET(self):
-        self.parsed_uri = urlparse.urlparse(self.path)
+        self.parsed_uri = urlparse.urlparse(urllib.unquote(self.path))
         self.query = {}
         for k, v in cgi.parse_qsl(self.parsed_uri[4]):
             self.query[k] = v.decode('utf-8')
         path = self.parsed_uri[2]
-        
+        print path 
 
         if path == "/":
             extra_headers = [('Content-type', 'text/plain')]
             else:
                 extra_headers = [('Content-type', 'text/plain')]
                 self._respond(200, extra_headers, "ok")
-                
+
+        elif path == "/éàù":
+            extra_headers = [('Content-type', 'text/plain')]
+            self._respond(200, extra_headers, "ok")
+
+        elif path == "/test":
+            extra_headers = [('Content-type', 'text/plain')]
+            self._respond(200, extra_headers, "ok")
+
         elif path == "/query":
             test = self.query.get("test", False)
             if test and test == "testing":
         for k, v in extra_headers:
             self.send_header(k, v)
         self.end_headers()
-        self.wfile.write(smart_str(body))
+        self.wfile.write(to_bytestring(body))
         self.wfile.close()
 
     def finish(self):

tests/resource_test.py

         result = self.res.get('/unicode')
         self.assert_(result == u"éàù@")
 
+    def testUrlWithAccents(self):
+        result = self.res.get('/éàù')
+        self.assert_(result == "ok")
+        self.assert_(result.http_code == 200)
+
+    def testUrlUnicode(self):
+        result = self.res.get(u'/test')
+        self.assert_(result == "ok")
+        self.assert_(result.http_code == 200)
+        result = self.res.get(u'/éàù')
+        self.assert_(result == "ok")
+        self.assert_(result.http_code == 200)
+
     def testGetWithContentType(self):
         result = self.res.get('/json', headers={'Content-Type': 'application/json'})
         self.assert_(result.http_code == 200)

tests/transports_test.py

         result = self.res.get('/unicode')
         self.assert_(result == u"éàù@")
 
-    def testPostByteString(self):
-        result = self.res.post('/bytestring', payload="éàù@")
-        self.assert_(result == "éàù@")
+    def testUrlWithAccents(self):
+        result = self.res.get('/éàù')
+        self.assert_(result == "ok")
+        self.assert_(result.http_code == 200)
+
+    def testUrlUnicode(self):
+        result = self.res.get(u'/test')
+        self.assert_(result == "ok")
+        self.assert_(result.http_code == 200)
 
     def testGetWithContentType(self):
         result = self.res.get('/json', headers={'Content-Type': 'application/json'})
         result = self.res.post(payload="test")
         self.assert_(result=="test")
 
+    def testPostByteString(self):
+        result = self.res.post('/bytestring', payload="éàù@")
+        self.assert_(result == "éàù@")
+
     def testPostUnicode(self):
-        result = self.res.get('/unicode', payload=u"éàù@")
+        result = self.res.post('/unicode', payload=u"éàù@")
         self.assert_(result == u"éàù@")
 
     def testPostWithContentType(self):