Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 39558200B7D for ; Sat, 10 Sep 2016 12:38:23 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 2D0FA160ABE; Sat, 10 Sep 2016 10:38:23 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id CB258160AB2 for ; Sat, 10 Sep 2016 12:38:21 +0200 (CEST) Received: (qmail 43061 invoked by uid 500); 10 Sep 2016 10:38:20 -0000 Mailing-List: contact dev-help@chemistry.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@chemistry.apache.org Delivered-To: mailing list dev@chemistry.apache.org Received: (qmail 43050 invoked by uid 99); 10 Sep 2016 10:38:20 -0000 Received: from arcas.apache.org (HELO arcas) (140.211.11.28) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 10 Sep 2016 10:38:20 +0000 Received: from arcas.apache.org (localhost [127.0.0.1]) by arcas (Postfix) with ESMTP id 931202C1B75 for ; Sat, 10 Sep 2016 10:38:20 +0000 (UTC) Date: Sat, 10 Sep 2016 10:38:20 +0000 (UTC) From: "Laurent Mignon (JIRA)" To: dev@chemistry.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Updated] (CMIS-996) BrowserBinding getObjecyByPath: unicode is not supported by urllib.quote MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 archived-at: Sat, 10 Sep 2016 10:38:23 -0000 [ https://issues.apache.org/jira/browse/CMIS-996?page=3Dcom.atlassian.= jira.plugin.system.issuetabpanels:all-tabpanel ] Laurent Mignon updated CMIS-996: -------------------------------- Description:=20 The function getObjectByPath use urllib.quote to quote the path into the ur= l. urllib.quote doesn't support unicode values.=20 see https://github.com/apache/chemistry-cmislib/pull/4 {code} From 144475d56aa4a8547f8c5a869f75697e6f653d99 Mon Sep 17 00:00:00 2001 From: Laurent Mignon Date: Fri, 9 Sep 2016 19:52:30 +0200 Subject: [PATCH] Fix UnicodeEncodeError when calling urllib.quote whith val= ue containing accented chars In the same time ensure that all the sources fil= es are in the same encoding as python itself (utf-8) by adding an encoding declaration at first line of any files. --- src/cmislib/atompub/binding.py | 1 + src/cmislib/browser/binding.py | 38 ++++++++++++++++++++++-------- src/cmislib/cmis_services.py | 1 + src/cmislib/domain.py | 1 + src/cmislib/exceptions.py | 1 + src/cmislib/messages.py | 1 + src/cmislib/model.py | 1 + src/cmislib/net.py | 1 + src/cmislib/util.py | 1 + src/tests/cmislibtest.py | 53 +++++++++++++++++++++-----------------= ---- 10 files changed, 63 insertions(+), 36 deletions(-) diff --git a/src/cmislib/atompub/binding.py b/src/cmislib/atompub/binding.p= y index f1a629f..55a066a 100644 --- a/src/cmislib/atompub/binding.py +++ b/src/cmislib/atompub/binding.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file diff --git a/src/cmislib/browser/binding.py b/src/cmislib/browser/binding.p= y index 7d7d758..c148a0c 100644 --- a/src/cmislib/browser/binding.py +++ b/src/cmislib/browser/binding.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file @@ -715,7 +716,7 @@ def getObjectByPath(self, path, **kwargs): - includeAllowableActions """ =20 - byPathUrl =3D self.getRootFolderUrl() + quote(path) + "?cmisselect= or=3Dobject" + byPathUrl =3D self.getRootFolderUrl() + safe_quote(path) + "?cmiss= elector=3Dobject" result =3D self._cmisClient.binding.get(byPathUrl.encode('utf-8'), self._cmisClient.username, self._cmisClient.password, @@ -926,7 +927,7 @@ def getTypeChildren(self, typesUrl =3D self.getRepositoryUrl() + "?cmisselector=3DtypeChildr= en" =20 if typeId is not None: - typesUrl +=3D "&typeId=3D%s" % (quote(typeId)) + typesUrl +=3D "&typeId=3D%s" % (safe_quote(typeId)) =20 result =3D self._cmisClient.binding.get(typesUrl, self._cmisClient.username, @@ -986,7 +987,7 @@ def getTypeDescendants(self, typeId=3DNone, depth=3DNon= e, **kwargs): typesUrl =3D self.getRepositoryUrl() + "?cmisselector=3DtypeDescen= dants" =20 if typeId is not None: - typesUrl +=3D "&typeId=3D%s" % (quote(typeId)) + typesUrl +=3D "&typeId=3D%s" % (safe_quote(typeId)) if depth is not None: typesUrl +=3D "&depth=3D%s" % (depth) print typesUrl @@ -1180,7 +1181,7 @@ def query(self, statement, **kwargs): """ =20 # build the CMIS query XML that we're going to POST - queryUrl =3D self.getRepositoryUrl() + "?cmisaction=3Dquery&q=3D" = + quote(statement) + queryUrl =3D self.getRepositoryUrl() + "?cmisaction=3Dquery&q=3D" = + safe_quote(statement) =20 # do the POST result =3D self._cmisClient.binding.post(queryUrl.encode('utf-8'), @@ -3161,6 +3162,18 @@ def encode_multipart_formdata(fields, contentFile, c= ontentType): return content_type, body =20 =20 +def to_utf8(value): + + """ Safe encodng of value to utf-8 taking care of unicode values + """ + if isinstance(value, unicode): + value =3D value.encode('utf8') + elif isinstance(value, str): + # Must be encoded in UTF-8 + value.decode('utf8') + return value + + def safe_urlencode(in_dict): =20 """ @@ -3171,17 +3184,22 @@ def safe_urlencode(in_dict): def encoded_dict(in_dict): out_dict =3D {} for k, v in in_dict.iteritems(): - if isinstance(v, unicode): - v =3D v.encode('utf8') - elif isinstance(v, str): - # Must be encoded in UTF-8 - v.decode('utf8') - out_dict[k] =3D v + out_dict[k] =3D to_utf8(v) return out_dict =20 return urlencode(encoded_dict(in_dict)) =20 =20 +def safe_quote(value): + + """ + Safe encoding of value taking care of unicode value + urllib.quote doesn't like unicode values + """ + + return quote(to_utf8(value)) + + class ResultsSerializer(object): =20 """ diff --git a/src/cmislib/cmis_services.py b/src/cmislib/cmis_services.py index 8c59cdb..4659d02 100644 --- a/src/cmislib/cmis_services.py +++ b/src/cmislib/cmis_services.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file diff --git a/src/cmislib/domain.py b/src/cmislib/domain.py index a2f7a25..a362339 100644 --- a/src/cmislib/domain.py +++ b/src/cmislib/domain.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file diff --git a/src/cmislib/exceptions.py b/src/cmislib/exceptions.py index 207280d..58d601d 100644 --- a/src/cmislib/exceptions.py +++ b/src/cmislib/exceptions.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file diff --git a/src/cmislib/messages.py b/src/cmislib/messages.py index 2df8e45..0d49756 100644 --- a/src/cmislib/messages.py +++ b/src/cmislib/messages.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file diff --git a/src/cmislib/model.py b/src/cmislib/model.py index 0a04c09..03ede82 100644 --- a/src/cmislib/model.py +++ b/src/cmislib/model.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file diff --git a/src/cmislib/net.py b/src/cmislib/net.py index 3984918..e5124a9 100644 --- a/src/cmislib/net.py +++ b/src/cmislib/net.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file diff --git a/src/cmislib/util.py b/src/cmislib/util.py index 7b6855f..0a2ff6a 100644 --- a/src/cmislib/util.py +++ b/src/cmislib/util.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file diff --git a/src/tests/cmislibtest.py b/src/tests/cmislibtest.py index a81be56..c524bcf 100644 --- a/src/tests/cmislibtest.py +++ b/src/tests/cmislibtest.py @@ -346,32 +346,33 @@ def testGetFolder(self): def testGetObjectByPath(self): """Create test objects (one folder, one document) then try to get them by path""" - # names of folders and test docs - parentFolderName =3D 'testGetObjectByPath folder' - subFolderName =3D 'subfolder' - docName =3D 'testdoc' - - # create the folder structure - parentFolder =3D self._testFolder.createFolder(parentFolderName) - subFolder =3D parentFolder.createFolder(subFolderName) - # use the subfolder path to get the folder by path - subFolderPath =3D subFolder.getProperties().get("cmis:path") - searchFolder =3D self._repo.getObjectByPath(subFolderPath) - self.assertEquals(subFolder.getObjectId(), searchFolder.getObjectI= d()) - - # create a test doc - doc =3D subFolder.createDocument(docName) - # ask the doc for its paths - searchDocPaths =3D doc.getPaths() - # for each path in the list, try to get the object by path - # this is better than building a path with the doc's name b/c the = name - # isn't guaranteed to be used as the path segment (see CMIS-232) - for path in searchDocPaths: - searchDoc =3D self._repo.getObjectByPath(path) - self.assertEquals(doc.getObjectId(), searchDoc.getObjectId()) - - # get the subfolder by path, then ask for its children - subFolder =3D self._repo.getObjectByPath(subFolderPath) + # names of folders and test docs (without and with unicode char) + for suffix in ['', u'_=C3=A9=C3=A0=E2=82=AC$']: + parentFolderName =3D 'testGetObjectByPath folder' + suffix + subFolderName =3D 'subfolder' + suffix + docName =3D 'testdoc' + suffix + =20 + # create the folder structure + parentFolder =3D self._testFolder.createFolder(parentFolderNam= e) + subFolder =3D parentFolder.createFolder(subFolderName) + # use the subfolder path to get the folder by path + subFolderPath =3D subFolder.getProperties().get("cmis:path") + searchFolder =3D self._repo.getObjectByPath(subFolderPath) + self.assertEquals(subFolder.getObjectId(), searchFolder.getObj= ectId()) + =20 + # create a test doc + doc =3D subFolder.createDocument(docName) + # ask the doc for its paths + searchDocPaths =3D doc.getPaths() + # for each path in the list, try to get the object by path + # this is better than building a path with the doc's name b/c = the name + # isn't guaranteed to be used as the path segment (see CMIS-23= 2) + for path in searchDocPaths: + searchDoc =3D self._repo.getObjectByPath(path) + self.assertEquals(doc.getObjectId(), searchDoc.getObjectId= ()) + =20 + # get the subfolder by path, then ask for its children + subFolder =3D self._repo.getObjectByPath(subFolderPath) self.assertEquals(len(subFolder.getChildren().getResults()), 1) =20 # getting unfiled documents may work for the atom pub binding for some= servers {code} was: The function getObjectByPath use urllib.quote to quote the path into the ur= l. urllib.quote doesn't support unicode values.=20 see https://github.com/apache/chemistry-cmislib/pull/4 {code} diff --git a/src/cmislib/browser/binding.py b/src/cmislib/browser/binding.p= y index 7d7d758..fa20281 100644 --- a/src/cmislib/browser/binding.py +++ b/src/cmislib/browser/binding.py @@ -715,7 +715,7 @@ class BrowserRepository(object): - includeAllowableActions """ =20 - byPathUrl =3D self.getRootFolderUrl() + quote(path) + "?cmisselect= or=3Dobject" + byPathUrl =3D self.getRootFolderUrl() + safe_quote(path) + "?cmiss= elector=3Dobject" result =3D self._cmisClient.binding.get(byPathUrl.encode('utf-8'), self._cmisClient.username, self._cmisClient.password, @@ -926,7 +926,7 @@ class BrowserRepository(object): typesUrl =3D self.getRepositoryUrl() + "?cmisselector=3DtypeChildr= en" =20 if typeId is not None: - typesUrl +=3D "&typeId=3D%s" % (quote(typeId)) + typesUrl +=3D "&typeId=3D%s" % (safe_quote(typeId)) =20 result =3D self._cmisClient.binding.get(typesUrl, self._cmisClient.username, @@ -986,7 +986,7 @@ class BrowserRepository(object): typesUrl =3D self.getRepositoryUrl() + "?cmisselector=3DtypeDescen= dants" =20 if typeId is not None: - typesUrl +=3D "&typeId=3D%s" % (quote(typeId)) + typesUrl +=3D "&typeId=3D%s" % (safe_quote(typeId)) if depth is not None: typesUrl +=3D "&depth=3D%s" % (depth) print typesUrl @@ -1180,7 +1180,7 @@ class BrowserRepository(object): """ =20 # build the CMIS query XML that we're going to POST - queryUrl =3D self.getRepositoryUrl() + "?cmisaction=3Dquery&q=3D" = + quote(statement) + queryUrl =3D self.getRepositoryUrl() + "?cmisaction=3Dquery&q=3D" = + safe_quote(statement) =20 # do the POST result =3D self._cmisClient.binding.post(queryUrl.encode('utf-8'), @@ -3182,6 +3182,21 @@ def safe_urlencode(in_dict): return urlencode(encoded_dict(in_dict)) =20 =20 +def safe_quote(value): + + """ + Safe encoding of value taking care of unicode value + urllib.quote doesn't like unicode values + """ + + if isinstance(value, unicode): + value =3D value.encode('utf8') + elif isinstance(value, str): + # Must be encoded in UTF-8 + value.decode('utf8') + return quote(value) + + class ResultsSerializer(object): =20 """ diff --git a/src/tests/cmislibtest.py b/src/tests/cmislibtest.py index a81be56..2ec128d 100644 --- a/src/tests/cmislibtest.py +++ b/src/tests/cmislibtest.py @@ -374,6 +374,38 @@ class RepositoryTest(CmisTestBase): subFolder =3D self._repo.getObjectByPath(subFolderPath) self.assertEquals(len(subFolder.getChildren().getResults()), 1) =20 + def testGetObjectByPathUnicode(self): + """Create test objects (one folder, one document) then try to get + them by path""" + # names of folders and test docs + parentFolderName =3D 'testGetObjectByPath folder' + subFolderName =3D u'subfolder_=C3=A9=C3=A0' + docName =3D u'testdoc_=C3=A9=C3=A0' + + # create the folder structure + parentFolder =3D self._testFolder.createFolder(parentFolderName) + subFolder =3D parentFolder.createFolder(subFolderName) + # use the subfolder path to get the folder by path + subFolderPath =3D subFolder.getProperties().get("cmis:path") + searchFolder =3D self._repo.getObjectByPath(subFolderPath) + self.assertEquals(subFolder.getObjectId(), searchFolder.getObjectI= d()) + + # create a test doc + doc =3D subFolder.createDocument(docName) + # ask the doc for its paths + searchDocPaths =3D doc.getPaths() + # for each path in the list, try to get the object by path + # this is better than building a path with the doc's name b/c the = name + # isn't guaranteed to be used as the path segment (see CMIS-232) + for path in searchDocPaths: + searchDoc =3D self._repo.getObjectByPath(path) + self.assertEquals(doc.getObjectId(), searchDoc.getObjectId()) + + # get the subfolder by path, then ask for its children + subFolder =3D self._repo.getObjectByPath(subFolderPath) + self.assertEquals(len(subFolder.getChildren().getResults()), 1) + + # getting unfiled documents may work for the atom pub binding for some= servers # but it isn't part of the spec so removing this test for now ''' {code} > BrowserBinding getObjecyByPath: unicode is not supported by urllib.quote > ------------------------------------------------------------------------ > > Key: CMIS-996 > URL: https://issues.apache.org/jira/browse/CMIS-996 > Project: Chemistry > Issue Type: Bug > Components: python-cmislib > Reporter: Laurent Mignon > Assignee: Jeff Potts > > The function getObjectByPath use urllib.quote to quote the path into the = url. urllib.quote doesn't support unicode values.=20 > see https://github.com/apache/chemistry-cmislib/pull/4 > {code} > From 144475d56aa4a8547f8c5a869f75697e6f653d99 Mon Sep 17 00:00:00 2001 > From: Laurent Mignon > Date: Fri, 9 Sep 2016 19:52:30 +0200 > Subject: [PATCH] Fix UnicodeEncodeError when calling urllib.quote whith v= alue > containing accented chars In the same time ensure that all the sources f= iles > are in the same encoding as python itself (utf-8) by adding an encoding > declaration at first line of any files. > --- > src/cmislib/atompub/binding.py | 1 + > src/cmislib/browser/binding.py | 38 ++++++++++++++++++++++-------- > src/cmislib/cmis_services.py | 1 + > src/cmislib/domain.py | 1 + > src/cmislib/exceptions.py | 1 + > src/cmislib/messages.py | 1 + > src/cmislib/model.py | 1 + > src/cmislib/net.py | 1 + > src/cmislib/util.py | 1 + > src/tests/cmislibtest.py | 53 +++++++++++++++++++++---------------= ------ > 10 files changed, 63 insertions(+), 36 deletions(-) > diff --git a/src/cmislib/atompub/binding.py b/src/cmislib/atompub/binding= .py > index f1a629f..55a066a 100644 > --- a/src/cmislib/atompub/binding.py > +++ b/src/cmislib/atompub/binding.py > @@ -1,3 +1,4 @@ > +# -*- coding: utf-8 -*- > # > # Licensed to the Apache Software Foundation (ASF) under one > # or more contributor license agreements. See the NOTICE file > diff --git a/src/cmislib/browser/binding.py b/src/cmislib/browser/binding= .py > index 7d7d758..c148a0c 100644 > --- a/src/cmislib/browser/binding.py > +++ b/src/cmislib/browser/binding.py > @@ -1,3 +1,4 @@ > +# -*- coding: utf-8 -*- > # > # Licensed to the Apache Software Foundation (ASF) under one > # or more contributor license agreements. See the NOTICE file > @@ -715,7 +716,7 @@ def getObjectByPath(self, path, **kwargs): > - includeAllowableActions > """ > =20 > - byPathUrl =3D self.getRootFolderUrl() + quote(path) + "?cmissele= ctor=3Dobject" > + byPathUrl =3D self.getRootFolderUrl() + safe_quote(path) + "?cmi= sselector=3Dobject" > result =3D self._cmisClient.binding.get(byPathUrl.encode('utf-8'= ), > self._cmisClient.username, > self._cmisClient.password, > @@ -926,7 +927,7 @@ def getTypeChildren(self, > typesUrl =3D self.getRepositoryUrl() + "?cmisselector=3DtypeChil= dren" > =20 > if typeId is not None: > - typesUrl +=3D "&typeId=3D%s" % (quote(typeId)) > + typesUrl +=3D "&typeId=3D%s" % (safe_quote(typeId)) > =20 > result =3D self._cmisClient.binding.get(typesUrl, > self._cmisClient.username, > @@ -986,7 +987,7 @@ def getTypeDescendants(self, typeId=3DNone, depth=3DN= one, **kwargs): > typesUrl =3D self.getRepositoryUrl() + "?cmisselector=3DtypeDesc= endants" > =20 > if typeId is not None: > - typesUrl +=3D "&typeId=3D%s" % (quote(typeId)) > + typesUrl +=3D "&typeId=3D%s" % (safe_quote(typeId)) > if depth is not None: > typesUrl +=3D "&depth=3D%s" % (depth) > print typesUrl > @@ -1180,7 +1181,7 @@ def query(self, statement, **kwargs): > """ > =20 > # build the CMIS query XML that we're going to POST > - queryUrl =3D self.getRepositoryUrl() + "?cmisaction=3Dquery&q=3D= " + quote(statement) > + queryUrl =3D self.getRepositoryUrl() + "?cmisaction=3Dquery&q=3D= " + safe_quote(statement) > =20 > # do the POST > result =3D self._cmisClient.binding.post(queryUrl.encode('utf-8'= ), > @@ -3161,6 +3162,18 @@ def encode_multipart_formdata(fields, contentFile,= contentType): > return content_type, body > =20 > =20 > +def to_utf8(value): > + > + """ Safe encodng of value to utf-8 taking care of unicode values > + """ > + if isinstance(value, unicode): > + value =3D value.encode('utf8') > + elif isinstance(value, str): > + # Must be encoded in UTF-8 > + value.decode('utf8') > + return value > + > + > def safe_urlencode(in_dict): > =20 > """ > @@ -3171,17 +3184,22 @@ def safe_urlencode(in_dict): > def encoded_dict(in_dict): > out_dict =3D {} > for k, v in in_dict.iteritems(): > - if isinstance(v, unicode): > - v =3D v.encode('utf8') > - elif isinstance(v, str): > - # Must be encoded in UTF-8 > - v.decode('utf8') > - out_dict[k] =3D v > + out_dict[k] =3D to_utf8(v) > return out_dict > =20 > return urlencode(encoded_dict(in_dict)) > =20 > =20 > +def safe_quote(value): > + > + """ > + Safe encoding of value taking care of unicode value > + urllib.quote doesn't like unicode values > + """ > + > + return quote(to_utf8(value)) > + > + > class ResultsSerializer(object): > =20 > """ > diff --git a/src/cmislib/cmis_services.py b/src/cmislib/cmis_services.py > index 8c59cdb..4659d02 100644 > --- a/src/cmislib/cmis_services.py > +++ b/src/cmislib/cmis_services.py > @@ -1,3 +1,4 @@ > +# -*- coding: utf-8 -*- > # > # Licensed to the Apache Software Foundation (ASF) under one > # or more contributor license agreements. See the NOTICE file > diff --git a/src/cmislib/domain.py b/src/cmislib/domain.py > index a2f7a25..a362339 100644 > --- a/src/cmislib/domain.py > +++ b/src/cmislib/domain.py > @@ -1,3 +1,4 @@ > +# -*- coding: utf-8 -*- > # > # Licensed to the Apache Software Foundation (ASF) under one > # or more contributor license agreements. See the NOTICE file > diff --git a/src/cmislib/exceptions.py b/src/cmislib/exceptions.py > index 207280d..58d601d 100644 > --- a/src/cmislib/exceptions.py > +++ b/src/cmislib/exceptions.py > @@ -1,3 +1,4 @@ > +# -*- coding: utf-8 -*- > # > # Licensed to the Apache Software Foundation (ASF) under one > # or more contributor license agreements. See the NOTICE file > diff --git a/src/cmislib/messages.py b/src/cmislib/messages.py > index 2df8e45..0d49756 100644 > --- a/src/cmislib/messages.py > +++ b/src/cmislib/messages.py > @@ -1,3 +1,4 @@ > +# -*- coding: utf-8 -*- > # > # Licensed to the Apache Software Foundation (ASF) under one > # or more contributor license agreements. See the NOTICE file > diff --git a/src/cmislib/model.py b/src/cmislib/model.py > index 0a04c09..03ede82 100644 > --- a/src/cmislib/model.py > +++ b/src/cmislib/model.py > @@ -1,3 +1,4 @@ > +# -*- coding: utf-8 -*- > # > # Licensed to the Apache Software Foundation (ASF) under one > # or more contributor license agreements. See the NOTICE file > diff --git a/src/cmislib/net.py b/src/cmislib/net.py > index 3984918..e5124a9 100644 > --- a/src/cmislib/net.py > +++ b/src/cmislib/net.py > @@ -1,3 +1,4 @@ > +# -*- coding: utf-8 -*- > # > # Licensed to the Apache Software Foundation (ASF) under one > # or more contributor license agreements. See the NOTICE file > diff --git a/src/cmislib/util.py b/src/cmislib/util.py > index 7b6855f..0a2ff6a 100644 > --- a/src/cmislib/util.py > +++ b/src/cmislib/util.py > @@ -1,3 +1,4 @@ > +# -*- coding: utf-8 -*- > # > # Licensed to the Apache Software Foundation (ASF) under one > # or more contributor license agreements. See the NOTICE file > diff --git a/src/tests/cmislibtest.py b/src/tests/cmislibtest.py > index a81be56..c524bcf 100644 > --- a/src/tests/cmislibtest.py > +++ b/src/tests/cmislibtest.py > @@ -346,32 +346,33 @@ def testGetFolder(self): > def testGetObjectByPath(self): > """Create test objects (one folder, one document) then try to ge= t > them by path""" > - # names of folders and test docs > - parentFolderName =3D 'testGetObjectByPath folder' > - subFolderName =3D 'subfolder' > - docName =3D 'testdoc' > - > - # create the folder structure > - parentFolder =3D self._testFolder.createFolder(parentFolderName) > - subFolder =3D parentFolder.createFolder(subFolderName) > - # use the subfolder path to get the folder by path > - subFolderPath =3D subFolder.getProperties().get("cmis:path") > - searchFolder =3D self._repo.getObjectByPath(subFolderPath) > - self.assertEquals(subFolder.getObjectId(), searchFolder.getObjec= tId()) > - > - # create a test doc > - doc =3D subFolder.createDocument(docName) > - # ask the doc for its paths > - searchDocPaths =3D doc.getPaths() > - # for each path in the list, try to get the object by path > - # this is better than building a path with the doc's name b/c th= e name > - # isn't guaranteed to be used as the path segment (see CMIS-232) > - for path in searchDocPaths: > - searchDoc =3D self._repo.getObjectByPath(path) > - self.assertEquals(doc.getObjectId(), searchDoc.getObjectId()= ) > - > - # get the subfolder by path, then ask for its children > - subFolder =3D self._repo.getObjectByPath(subFolderPath) > + # names of folders and test docs (without and with unicode char) > + for suffix in ['', u'_=C3=A9=C3=A0=E2=82=AC$']: > + parentFolderName =3D 'testGetObjectByPath folder' + suffix > + subFolderName =3D 'subfolder' + suffix > + docName =3D 'testdoc' + suffix > + =20 > + # create the folder structure > + parentFolder =3D self._testFolder.createFolder(parentFolderN= ame) > + subFolder =3D parentFolder.createFolder(subFolderName) > + # use the subfolder path to get the folder by path > + subFolderPath =3D subFolder.getProperties().get("cmis:path") > + searchFolder =3D self._repo.getObjectByPath(subFolderPath) > + self.assertEquals(subFolder.getObjectId(), searchFolder.getO= bjectId()) > + =20 > + # create a test doc > + doc =3D subFolder.createDocument(docName) > + # ask the doc for its paths > + searchDocPaths =3D doc.getPaths() > + # for each path in the list, try to get the object by path > + # this is better than building a path with the doc's name b/= c the name > + # isn't guaranteed to be used as the path segment (see CMIS-= 232) > + for path in searchDocPaths: > + searchDoc =3D self._repo.getObjectByPath(path) > + self.assertEquals(doc.getObjectId(), searchDoc.getObject= Id()) > + =20 > + # get the subfolder by path, then ask for its children > + subFolder =3D self._repo.getObjectByPath(subFolderPath) > self.assertEquals(len(subFolder.getChildren().getResults()), 1) > =20 > # getting unfiled documents may work for the atom pub binding for so= me servers > {code} -- This message was sent by Atlassian JIRA (v6.3.4#6332)