[Python-modules-commits] [sparqlwrapper] 01/11: New upstream version 1.7.6

chrysn chrysn-guest at moszumanska.debian.org
Wed Nov 16 11:11:31 UTC 2016


This is an automated email from the git hooks/post-receive script.

chrysn-guest pushed a commit to branch master
in repository sparqlwrapper.

commit ecd5c3dc5869e3bc4f0cc7f8c41a8a93eb8ab291
Author: chrysn <chrysn at fsfe.org>
Date:   Tue Nov 8 15:18:51 2016 +0100

    New upstream version 1.7.6
---
 .gitignore                        |   3 +
 .travis.yml                       |  17 +++
 AUTHORS.md                        |  26 +++++
 AUTHORS.txt                       |  23 ----
 ChangeLog.txt                     |  31 ++++-
 MANAGEMENT.md                     |  38 ++++++
 MANIFEST.in                       |   5 +-
 Makefile                          |   6 +-
 README.md                         |   9 +-
 SPARQLWrapper/SPARQLExceptions.py |   4 +-
 SPARQLWrapper/SmartWrapper.py     |   4 +
 SPARQLWrapper/Wrapper.py          | 235 ++++++++++++++++++++++++++-----------
 SPARQLWrapper/__init__.py         |  28 +++--
 SPARQLWrapper/jsonlayer.py        | 164 --------------------------
 requirements.txt                  |   2 +
 run_tests_py3.sh                  |  38 ++++++
 setup.py                          |  70 +++++++----
 test/dbpedia.py                   |  14 ++-
 test/wrapper_test.py              | 238 ++++++++++++++++++++++++++++++++++----
 tests.sh                          |  13 +++
 20 files changed, 645 insertions(+), 323 deletions(-)

diff --git a/.gitignore b/.gitignore
index f4e77d5..61757a4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,6 @@
 SPARQLWrapper.egg-info
 build
 dist
+doc
+.idea
+*.iml
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..66f3ae9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,17 @@
+# http://travis-ci.org/RDFLib/sparqlwrapper
+
+sudo: false
+
+language: python
+
+python:
+    - 2.7
+    - 3.2
+    - 3.3
+    - 3.4
+    - pypy
+
+install:
+    - python setup.py sdist && pip install ./dist/*
+
+script: ./tests.sh 
diff --git a/AUTHORS.md b/AUTHORS.md
new file mode 100644
index 0000000..5bcb36e
--- /dev/null
+++ b/AUTHORS.md
@@ -0,0 +1,26 @@
+# Authors
+
+* Ivan Herman ([@iherman](http://github.com/iherman))  
+* Sergio Fernández ([@wikier](http://github.com/wikier))
+* Carlos Tejo ([@dayures](http://github.com/dayures))
+* Alexey Zakhlestin ([@indeyets](http://github.com/indeyets))
+
+# Contributors
+
+* Obey Arthur Liu ([@ArthurLiu](http://github.com/ArthurLiu)): different patches
+* Christopher Lenz ([@cmlenz](http://github.com/cmlenz)): feature to allow developers to choose the json module
+* Pēteris Caune ([@cuu508](http://github.com/cuu508)): great feedback and patches
+* Bogdan Benea ([bugdone at users.sourceforge.net](mailto:bugdone at users.sourceforge.net)), patch for the query regular expresion
+* William Waites ([@wwaites](http://github.com/wwaites)): patches for RDFLib3 
+* Christoph Burgmer ([@cburgmer](http://github.com/cburgmer)): patches for RDFLib3
+* Thomas Kluyver ([@takluyver](http://github.com/takluyver)): patches for Python 3.x
+* Diego Berrueta ([@berrueta](http://github.com/berrueta)): new function for printing results as table
+* Olivier Berger ([@olberger](http://github.com/olberger)): patch regarding raw response for unknown formats
+* Benjamin Cogrel ([@bcogrel](http://github.com/bcogrel)): standard query types
+* Urs Holzer ([@uholzer](http://github.com/uholzer)): features, patches and testing
+* Alf Lervåg ([@alf](http://github.com/alf)): setup patch
+* Nolan Nichols ([@nicholsn](http://github.com/nicholsn)): http disgest auth support
+* Kevin Turner ([@keturn](https://github.com/keturn)): `SmartWrapper.Value.__repr__()` implementation 
+* Marcelo Jorge Vieira ([@marcelometal](https://github.com/marcelometal)): typos
+* Trevor Andersen ([@trevorandersen](https://github.com/trevorandersen): patches for Python 3.x
+
diff --git a/AUTHORS.txt b/AUTHORS.txt
deleted file mode 100644
index 0d6740d..0000000
--- a/AUTHORS.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-Authors
--------
-                   
-    Ivan Herman <ivan at w3.org>   
-    Sergio Fernández <sergio.fernandez at salzburgresearch.at>
-    Carlos Tejo <carlos.tejo at fundacionctic.org>
-
-
-Contributors
-------------
-
-    Obey Arthur Liu <arthur at milliways.fr>, different patches
-    Christopher Lenz <cmlenz at gmx.de>, feature to allow developers to choose the json module
-    Pēteris Caune <cuu508 at gmail.com>, great feedback and patches
-    Bogdan Benea <bugdone at users.sourceforge.net>, patch for the query regular expresion
-    William Waites <ww at styx.org>, patches for RDFLib3 
-    Christoph Burgmer <cburgmer at users.sourceforge.net>, patches for RDFLib3
-    Thomas Kluyver <takowl at gmail.com>, patches for Python 3.x
-    Diego Berrueta <diego.berrueta at fundacionctic.org>, new function for printing results as table
-    Olivier Berger <olivier.berger at telecom-sudparis.eu>, patch regarding raw response for unknown formats
-    Alexey Zakhlestin <indeyets at gmail.com>, several patches
-
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 92cfb36..b45db5e 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,7 +1,36 @@
 SPARQLWrapper's changelog:
 -------------------------
 
-YYYY-MM-DD  1.6.1   - ...
+2015-12-18  1.7.6   - Removed wrong response encoding (issue #70)
+                    - Authorization header bug when using Python 3 (issue #71)
+
+2015-11-19  1.7.5   - Removed pip dependency on setup (issue #69)
+
+2015-11-05  1.7.4   - Fixed packaging (issue #66)
+
+2015-11-05  1.7.3   - Finally fixed the keepalive issue in all Pyhon versions  (issue #65)
+                    - Removed old JSON layer in favor of the native json module
+
+2015-11-03  1.7.2   - Moved to the new keepalive package (issues #53 and #61)
+
+2015-10-29  1.7.1   - Fixed build in Python 3.x (issue #57)
+
+2015-10-29  1.7.0   - Added support to HTTP Digest Auth Support (issue #45)
+                    - Improved print_results showing language tag (xml:lang) and datatype
+                    - Updated to RDFLib 4.x
+
+2014-08-26  1.6.4   - Fixed unicode problems on setup (issue #42)
+
+2014-08-26  1.6.3   - Fixed unicode problems with urllib in Python 3 (issue #35)
+                    - Restored SPARQLWrapper2 class (issue #36)
+                    - Enhanced warning for missing rdflib-jsonld (issue #38)
+                    - Fixed build system (issue #39)
+
+2014-07-24  1.6.2   - Fixed query type detection with comments (issue #32)
+
+2014-07-21  1.6.1   - Added missing query types (issue #17)
+                    - Added a new method to the API to select the request method to be fully SPARQL 1.1 Protocol compliant (issue #28)             
+                    - Improved the test suite coverage, including support to run the tests under Python 3.x (issues #20, #24 and #31)
 
 2014-05-09  1.6.0   - Returning raw response in case of unknown content type returned
                     - Fixed some issues with the last version of the SPARQL 1.1 Update Protocol
diff --git a/MANAGEMENT.md b/MANAGEMENT.md
new file mode 100644
index 0000000..c315eeb
--- /dev/null
+++ b/MANAGEMENT.md
@@ -0,0 +1,38 @@
+# Management documentation
+
+The project keeps a very low-profile on managing, so we try to keep it simple.
+
+## Contributions
+
+Every contributor (patchs, pull requests, new features, etc) gets part of ownership by be mentioned as contributor to the project (`AUTHORS.md`).
+
+## Release
+
+### Software
+
+The release process is quite simple, just few things have to be done:
+
+First, do not forget to update the changelog (`ChangeLog.txt` file). That information could be added later to the release at github.
+
+Then you have to [create a release](https://github.com/blog/1547-release-your-software) by tagging the master branch:
+
+    git tag x.y.z
+    git push --tags
+
+And then upload the release to pypi:
+
+    python setup.py register sdist --formats=gztar,zip bdist_egg upload
+
+Please, don't forget to increment to the next module (`SPARQLWrapper/__init__.py` file).
+
+### Documentation
+
+In order to provide online documentation, some steps need to be accomplished:
+
+1. First, generate the documentation using [epydoc](http://epydoc.sourceforge.net/) using the makefile
+
+	make doc
+
+2. And then upload the documentation generated (`doc` folder) to GitHub Pages (`gh-pages` branch).
+
+3. After that, the online version of the documentation would be available on [GitHub Pages](http://rdflib.github.io/sparqlwrapper/resources/doc).
diff --git a/MANIFEST.in b/MANIFEST.in
index 3ee7608..f0581d1 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,2 +1,5 @@
-include *.txt
+include *.md
 exclude Makefile
+include test/*.py
+include scripts/*.py
+include requirements.txt
diff --git a/Makefile b/Makefile
index b43d36d..4447be3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,13 @@
 # SPARQLWrapper Makefile
 
 NAME=SPARQLWrapper
+VERSION=`python -c "import SPARQLWrapper,sys;sys.stdout.write(SPARQLWrapper.__version__)";`
 DESTDIR =
 DOCDIR=doc
-PYTHON=python
 
 doc:	clean
 	mkdir -p $(DOCDIR)
-	epydoc -v -n $(NAME) -o $(DOCDIR) --html SPARQLWrapper
+	epydoc -v -n "$(NAME) $(VERSION)" -o $(DOCDIR) --html SPARQLWrapper
 
 clean:
-	rm -rf $(DOCDIR)
\ No newline at end of file
+	rm -rf $(DOCDIR)
diff --git a/README.md b/README.md
index 30a14ce..0c9084c 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,15 @@
 # SPARQL Endpoint interface to Python
 
+[![Build Status](https://secure.travis-ci.org/RDFLib/sparqlwrapper.svg?branch=master)](https://travis-ci.org/RDFLib/sparqlwrapper)
+[![PyPi version](https://badge.fury.io/py/SPARQLWrapper.svg)](https://pypi.python.org/pypi/SPARQLWrapper)
+
 The distribution contains:
 
-* `SPARQLWrapper`: the Python library. You should copy the directory somewhere into your PYTHONPATH. Alternatively, you can also run the disutils scrips:
+* `SPARQLWrapper`: the Python library. You should copy the directory somewhere into your `PYTHONPATH`. Alternatively, you can also run the distutils scripts:
 
     python setup.py install
 
-* `test`: some unit tests
+* `test`: some unit and integrations tests
   
-* `script`: some scripts to run the library against some SPARQL end-points.
+* `script`: some scripts to run the library against some SPARQL endpoints.
 
diff --git a/SPARQLWrapper/SPARQLExceptions.py b/SPARQLWrapper/SPARQLExceptions.py
index a0b0e18..a5c4dc1 100644
--- a/SPARQLWrapper/SPARQLExceptions.py
+++ b/SPARQLWrapper/SPARQLExceptions.py
@@ -36,7 +36,7 @@ class EndPointInternalError(SPARQLWrapperException):
 
 class QueryBadFormed(SPARQLWrapperException):
     """
-    Query Bad Formed exceptions
+    Query Bad Formed exception
     """
 
     msg = "a bad request has been sent to the endpoint, probably the sparql query is bad formed"
@@ -44,7 +44,7 @@ class QueryBadFormed(SPARQLWrapperException):
 
 class EndPointNotFound(SPARQLWrapperException):
     """
-    End Point Not Found exceptions
+    End Point Not Found exception
     """
 
     msg = "it was impossible to connect with the endpoint in that address, check if it is correct"
diff --git a/SPARQLWrapper/SmartWrapper.py b/SPARQLWrapper/SmartWrapper.py
index 4a7c6b8..ccc2659 100644
--- a/SPARQLWrapper/SmartWrapper.py
+++ b/SPARQLWrapper/SmartWrapper.py
@@ -61,6 +61,10 @@ class Value(object):
         except :
             pass
 
+    def __repr__(self):
+        cls = self.__class__.__name__
+        return "%s(%s:%r)" % (cls, self.type, self.value)
+
 ######################################################################################
 
 
diff --git a/SPARQLWrapper/Wrapper.py b/SPARQLWrapper/Wrapper.py
index ccde1a7..b0a0817 100644
--- a/SPARQLWrapper/Wrapper.py
+++ b/SPARQLWrapper/Wrapper.py
@@ -25,12 +25,14 @@
 
 import urllib
 import urllib2
+from urllib2 import urlopen as urlopener  # don't change the name: tests override it
 import socket
 import base64
 import re
+import sys
 import warnings
 
-import jsonlayer
+import json
 from KeyCaseInsensitiveDict import KeyCaseInsensitiveDict
 from SPARQLExceptions import QueryBadFormed, EndPointNotFound, EndPointInternalError
 from SPARQLUtils import deprecated
@@ -40,7 +42,7 @@ from SPARQLWrapper import __agent__
 JSON   = "json"
 JSONLD = "json-ld"
 XML    = "xml"
-TURTLE = "n3"
+TURTLE = "turtle"
 N3     = "n3"
 RDF    = "rdf"
 _allowedFormats = [JSON, XML, TURTLE, N3, RDF]
@@ -50,6 +52,11 @@ POST = "POST"
 GET  = "GET"
 _allowedRequests = [POST, GET]
 
+# Possible HTTP Authentication methods
+BASIC = "BASIC"
+DIGEST = "DIGEST"
+_allowedAuth = [BASIC, DIGEST]
+
 # Possible SPARQL/SPARUL query type
 SELECT     = "SELECT"
 CONSTRUCT  = "CONSTRUCT"
@@ -57,8 +64,20 @@ ASK        = "ASK"
 DESCRIBE   = "DESCRIBE"
 INSERT     = "INSERT"
 DELETE     = "DELETE"
-MODIFY     = "MODIFY"
-_allowedQueryTypes = [SELECT, CONSTRUCT, ASK, DESCRIBE, INSERT, DELETE, MODIFY]
+CREATE     = "CREATE"
+CLEAR      = "CLEAR"
+DROP       = "DROP"
+LOAD       = "LOAD"
+COPY       = "COPY"
+MOVE       = "MOVE"
+ADD        = "ADD"
+_allowedQueryTypes = [SELECT, CONSTRUCT, ASK, DESCRIBE, INSERT, DELETE, CREATE, CLEAR, DROP,
+                      LOAD, COPY, MOVE, ADD]
+
+# Possible methods to perform requests
+URLENCODED = "urlencoded"
+POSTDIRECTLY = "postdirectly"
+_REQUEST_METHODS  = [URLENCODED, POSTDIRECTLY]
 
 # Possible output format (mime types) that can be converted by the local script. Unfortunately,
 # it does not work by simply setting the return format, because there is still a certain level of confusion
@@ -79,13 +98,13 @@ _RDF_POSSIBLE    = _RDF_XML + _RDF_N3
 _SPARQL_POSSIBLE = _SPARQL_XML + _SPARQL_JSON + _RDF_XML + _RDF_N3
 _SPARQL_PARAMS   = ["query"]
 
-
 try:
     import rdflib_jsonld
     _allowedFormats.append(JSONLD)
     _RDF_POSSIBLE = _RDF_POSSIBLE + _RDF_JSONLD
 except ImportError:
-    warnings.warn("JSON-LD disabled because no suitable support has been found", RuntimeWarning)
+    #warnings.warn("JSON-LD disabled because no suitable support has been found", RuntimeWarning)
+    pass
 
 # This is very ugly. The fact is that the key for the choice of the output format is not defined. 
 # Virtuoso uses 'format', joseki uses 'output', rasqual seems to use "results", etc. Lee Feigenbaum 
@@ -111,8 +130,8 @@ class SPARQLWrapper(object):
     @ivar baseURI: the URI of the SPARQL service
     """
     pattern = re.compile(r"""
-                ((?P<base>(\s*BASE\s*<.*?>)\s*)|(?P<prefixes>(\s*PREFIX\s+.+:\s*<.*?>)\s*))*
-                (?P<queryType>(CONSTRUCT|SELECT|ASK|DESCRIBE|INSERT|DELETE|MODIFY))
+        ((?P<base>(\s*BASE\s*<.*?>)\s*)|(?P<prefixes>(\s*PREFIX\s+.+:\s*<.*?>)\s*))*
+        (?P<queryType>(CONSTRUCT|SELECT|ASK|DESCRIBE|INSERT|DELETE|CREATE|CLEAR|DROP|LOAD|COPY|MOVE|ADD))
     """, re.VERBOSE | re.IGNORECASE)
 
     def __init__(self, endpoint, updateEndpoint=None, returnFormat=XML, defaultGraph=None, agent=__agent__):
@@ -141,6 +160,7 @@ class SPARQLWrapper(object):
         self.agent = agent
         self.user = None
         self.passwd = None
+        self.http_auth = BASIC
         self._defaultGraph = defaultGraph
 
         if returnFormat in _allowedFormats:
@@ -158,18 +178,30 @@ class SPARQLWrapper(object):
             self.addParameter("default-graph-uri", self._defaultGraph)
         self.returnFormat = self._defaultReturnFormat
         self.method = GET
-        self.queryType = SELECT
-        self.queryString = """SELECT * WHERE{ ?s ?p ?o }"""
+        self.setQuery("""SELECT * WHERE{ ?s ?p ?o }""")
         self.timeout = None
+        self.requestMethod = URLENCODED
 
     def setReturnFormat(self, format):
         """Set the return format. If not an allowed value, the setting is ignored.
 
         @param format: Possible values: are L{JSON}, L{XML}, L{TURTLE}, L{N3}, L{RDF} (constants in this module). All other cases are ignored.
-        @type format: string
+        @type format: str
         """
         if format in _allowedFormats :
             self.returnFormat = format
+        elif format == JSONLD:
+            raise ValueError("Current instance does not support JSON-LD; you might want to install the rdflib-json package.")
+        else:
+            raise ValueError("Invalid format '%s'; current instance supports: %s.", (format, ", ".join(_allowedFormats)))
+
+    def supportsReturnFormat(self, format):
+        """Check if a return format is supported.
+
+        @param format: Possible values: are L{JSON}, L{XML}, L{TURTLE}, L{N3}, L{RDF} (constants in this module). All other cases are ignored.
+        @type format: bool
+        """
+        return (format in _allowedFormats)
 
     def setTimeout(self, timeout):
         """Set the timeout (in seconds) to use for querying the endpoint.
@@ -179,6 +211,21 @@ class SPARQLWrapper(object):
         """
         self.timeout = int(timeout)
 
+    def setRequestMethod(self, method):
+        """Set the internal method to use to perform the request for query or
+        update operations, either URL-encoded (C{SPARQLWrapper.URLENCODED}) or 
+        POST directly (C{SPARQLWrapper.POSTDIRECTLY}).
+        Further details at U{http://www.w3.org/TR/sparql11-protocol/#query-operation}
+        and U{http://www.w3.org/TR/sparql11-protocol/#update-operation}.
+
+        @param method: method
+        @type method: str
+        """
+        if method in _REQUEST_METHODS:
+            self.requestMethod = method
+        else:
+            warnings.warn("invalid update method '%s'" % method, RuntimeWarning)
+
     @deprecated
     def addDefaultGraph(self, uri):
         """
@@ -262,7 +309,7 @@ class SPARQLWrapper(object):
             except KeyError:
                 return False
 
-    def setCredentials(self,user,passwd):
+    def setCredentials(self, user, passwd):
         """
             Set the credentials for querying the current endpoint
             @param user: username
@@ -273,6 +320,20 @@ class SPARQLWrapper(object):
         self.user = user
         self.passwd = passwd
 
+    def setHTTPAuth(self, auth):
+        """
+           Set the HTTP Authentication type (Basic or Digest)
+           @param auth: auth type
+           @type auth: string
+        """
+        if not isinstance(auth, str):
+            raise TypeError('setHTTPAuth takes a string')
+        elif auth.upper() in _allowedAuth:
+            self.http_auth = auth.upper()
+        else:
+            valid_types = ", ".join(_allowedAuth)
+            raise ValueError("Value should be one of {0}".format(valid_types))
+                    
     def setQuery(self, query):
         """
             Set the SPARQL query text. Note: no check is done on the validity of the query 
@@ -282,6 +343,21 @@ class SPARQLWrapper(object):
             @type query: string
             @bug: #2320024
         """
+        if sys.version < '3':  # have to write it like this, for 2to3 compatibility
+            if isinstance(query, unicode):
+                pass
+            elif isinstance(query, str):
+                query = query.decode('utf-8')
+            else:
+                raise TypeError('setQuery takes either unicode-strings or utf-8 encoded byte-strings')
+        else:
+            if isinstance(query, str):
+                pass
+            elif isinstance(query, bytes):
+                query = query.decode('utf-8')
+            else:
+                raise TypeError('setQuery takes either unicode-strings or utf-8 encoded byte-strings')
+
         self.queryString = query
         self.queryType   = self._parseQueryType(query)
 
@@ -299,6 +375,8 @@ class SPARQLWrapper(object):
             @rtype: string
         """
         try:
+            query = query if type(query)==str else query.encode('ascii', 'ignore')
+            query = re.sub(re.compile("#.*?\n" ), "" , query) # remove all occurance singleline comments (issue #32)
             r_queryType = self.pattern.search(query).group("queryType").upper()
         except AttributeError:
             warnings.warn("not detected query type for query '%s'" % query.replace("\n", " "), RuntimeWarning)
@@ -319,21 +397,21 @@ class SPARQLWrapper(object):
 
     def setUseKeepAlive(self):
         """Make urllib2 use keep-alive.
-        @raise ImportError: when could not be imported urlgrabber.keepalive.HTTPHandler
+        @raise ImportError: when could not be imported keepalive.HTTPHandler
         """
         try:
-            from urlgrabber.keepalive import HTTPHandler
+            from keepalive import HTTPHandler
             keepalive_handler = HTTPHandler()
             opener = urllib2.build_opener(keepalive_handler)
             urllib2.install_opener(opener)
         except ImportError:
-            warnings.warn("urlgrabber not installed in the system. The execution of this method has no effect.")
+            warnings.warn("keepalive support not available, so the execution of this method has no effect")
 
     def isSparqlUpdateRequest(self):
         """ Returns TRUE if SPARQLWrapper is configured for executing SPARQL Update request
         @return: bool
         """
-        return self.queryType in [INSERT, DELETE, MODIFY]
+        return self.queryType in [INSERT, DELETE, CREATE, CLEAR, DROP, LOAD, COPY, MOVE, ADD]
 
     def isSparqlQueryRequest(self):
         """ Returns TRUE if SPARQLWrapper is configured for executing SPARQL Query request
@@ -341,35 +419,29 @@ class SPARQLWrapper(object):
         """
         return not self.isSparqlUpdateRequest()
 
-    def _getRequestParameters(self):
-        queryParameters = self.parameters.copy()
+    def _getRequestEncodedParameters(self, query=None):
+        query_parameters = self.parameters.copy()
 
-        if self.isSparqlUpdateRequest():
-            queryParameters["update"] = [self.queryString]
-        else:
-            queryParameters["query"] = [self.queryString]
+        if query and type(query) == tuple and len(query) == 2:
+            #tuple ("query"/"update", queryString)
+            query_parameters[query[0]] = [query[1]]
 
         # This is very ugly. The fact is that the key for the choice of the output format is not defined.
         # Virtuoso uses 'format',sparqler uses 'output'
         # However, these processors are (hopefully) oblivious to the parameters they do not understand.
         # So: just repeat all possibilities in the final URI. UGLY!!!!!!!
         for f in _returnFormatSetting:
-            queryParameters[f] = [self.returnFormat]
+            query_parameters[f] = [self.returnFormat]
 
-        utfQueryParameters = {}
+        pairs = (
+            "%s=%s" % (
+                urllib.quote_plus(param.encode('UTF-8'), safe='/'),
+                urllib.quote_plus(value.encode('UTF-8'), safe='/')
+            )
+            for param, values in query_parameters.items() for value in values
+        )
 
-        for k, vs in queryParameters.items():
-            encodedValues = []
-
-            for v in vs:
-                if isinstance(v, unicode):
-                    encodedValues.append(v.encode('utf-8'))
-                else:
-                    encodedValues.append(v)
-
-            utfQueryParameters[k] = encodedValues
-
-        return utfQueryParameters
+        return '&'.join(pairs)
 
     def _getAcceptHeader(self):
         if self.queryType in [SELECT, ASK]:
@@ -379,7 +451,7 @@ class SPARQLWrapper(object):
                 acceptHeader = ",".join(_SPARQL_JSON)
             else:
                 acceptHeader = ",".join(_ALL)
-        elif self.queryType in [INSERT, DELETE, MODIFY]:
+        elif self.queryType in [INSERT, DELETE]:
             acceptHeader = "*/*"
         else:
             if self.returnFormat == N3 or self.returnFormat == TURTLE:
@@ -397,24 +469,56 @@ class SPARQLWrapper(object):
         C{urllib2.Request} object of the urllib2 Python library
         @return: request
         """
+        request = None
+
         if self.isSparqlUpdateRequest():
+            #protocol details at http://www.w3.org/TR/sparql11-protocol/#update-operation
             uri = self.updateEndpoint
+
+            if self.method != POST:
+                warnings.warn("update operations MUST be done by POST")
+
+            if self.requestMethod == POSTDIRECTLY:
+                request = urllib2.Request(uri + "?" + self._getRequestEncodedParameters())
+                request.add_header("Content-Type", "application/sparql-update")
+                request.data = self.queryString.encode('UTF-8')
+            else:  # URL-encoded
+                request = urllib2.Request(uri)
+                request.add_header("Content-Type", "application/x-www-form-urlencoded")
+                request.data = self._getRequestEncodedParameters(("update", self.queryString)).encode('ascii')
         else:
+            #protocol details at http://www.w3.org/TR/sparql11-protocol/#query-operation
             uri = self.endpoint
 
-        encodedParameters = urllib.urlencode(self._getRequestParameters(), True)
-
-        if self.method == POST:
-            request = urllib2.Request(uri)
-            request.add_header("Content-Type", "application/x-www-form-urlencoded")
-            request.add_data(encodedParameters)
-        else:  # GET
-            request = urllib2.Request(uri + "?" + encodedParameters)
+            if self.method == POST:
+                if self.requestMethod == POSTDIRECTLY:
+                    request = urllib2.Request(uri + "?" + self._getRequestEncodedParameters())
+                    request.add_header("Content-Type", "application/sparql-query")
+                    request.data = self.queryString.encode('UTF-8')
+                else:  # URL-encoded
+                    request = urllib2.Request(uri)
+                    request.add_header("Content-Type", "application/x-www-form-urlencoded")
+                    request.data = self._getRequestEncodedParameters(("query", self.queryString)).encode('ascii')
+            else:  # GET
+                request = urllib2.Request(uri + "?" + self._getRequestEncodedParameters(("query", self.queryString)))
 
         request.add_header("User-Agent", self.agent)
         request.add_header("Accept", self._getAcceptHeader())
         if self.user and self.passwd:
-            request.add_header("Authorization", "Basic " + base64.encodestring("%s:%s" % (self.user, self.passwd)))
+            if self.http_auth == BASIC:
+                credentials = "%s:%s" % (self.user, self.passwd)
+                request.add_header("Authorization", "Basic %s" % base64.b64encode(credentials.encode('utf-8')).decode('utf-8'))
+            elif self.http_auth == DIGEST:
+                realm = "SPARQL"
+                pwd_mgr = urllib2.HTTPPasswordMgr()
+                pwd_mgr.add_password(realm, uri, self.user, self.passwd)
+                opener = urllib2.build_opener()
+                opener.add_handler(urllib2.HTTPDigestAuthHandler(pwd_mgr))
+                urllib2.install_opener(opener)
+            else:
+                valid_types = ", ".join(_allowedAuth)
+                raise NotImplementedError("Expecting one of: {0}, but received: {1}".format(valid_types,
+                                                                                            self.http_auth))
 
         return request
 
@@ -424,10 +528,13 @@ class SPARQLWrapper(object):
 
         @return: tuples with the raw request plus the expected format
         """
-        if (self.timeout): socket.setdefaulttimeout(self.timeout)
+        if self.timeout:
+            socket.setdefaulttimeout(self.timeout)
+
         request = self._createRequest()
+
         try:
-            response = urllib2.urlopen(request)
+            response = urlopener(request)
             return response, self.returnFormat
         except urllib2.HTTPError, e:
             if e.code == 400:
@@ -524,20 +631,6 @@ class QueryResult(object):
         """Method for the standard iterator."""
         return self.response.next()
 
-    @staticmethod
-    def setJSONModule(module):
-        """Set the Python module for encoding JSON data. If not an allowed value, the setting is ignored.
-           JSON modules supported:
-             - ``simplejson``: http://code.google.com/p/simplejson/
-             - ``cjson``: http://pypi.python.org/pypi/python-cjson
-             - ``json``: This is the version of ``simplejson`` that is bundled with the
-               Python standard library since version 2.6
-               (see http://docs.python.org/library/json.html)
-        @param module: Possible values: are L{simplejson}, L{cjson}, L{json}. All other cases raise a ValueError exception.
-        @type module: string
-        """
-        jsonlayer.use(module)
-
     def _convertJSON(self):
         """
         Convert a JSON result into a Python dict. This method can be overwritten in a subclass
@@ -545,7 +638,7 @@ class QueryResult(object):
         @return: converted result
         @rtype: Python dictionary
         """
-        return jsonlayer.decode(self.response.read().decode("utf-8"))
+        return json.loads(self.response.read().decode("utf-8"))
 
     def _convertXML(self):
         """
@@ -650,7 +743,8 @@ class QueryResult(object):
         for result in results["results"]["bindings"] :
             index = 0
             for var in results["head"]["vars"] :
-                print result[var]["value"].ljust(width[index]),"|",
+                result = self.__get_prettyprint_string_sparql_var_result(result[var])
+                print result.ljust(width[index]),"|",
                 index += 1
             print
 
@@ -661,6 +755,17 @@ class QueryResult(object):
         for result in results["results"]["bindings"] :
             index = 0
             for var in results["head"]["vars"] :
-                width[index] = max(width[index], len(result[var]["value"]))
+                result = self.__get_prettyprint_string_sparql_var_result(result[var])
+                width[index] = max(width[index], len(result))
                 index =+ 1
         return width
+
+    def __get_prettyprint_string_sparql_var_result(self, result):
+        value = result["value"]
+        lang = result.get("xml:lang", None)
+        datatype = result.get("datatype",None)
+        if lang is not None:
+            value+="@"+lang
+        if datatype is not None:
+            value+=" ["+datatype+"]"
+        return value
diff --git a/SPARQLWrapper/__init__.py b/SPARQLWrapper/__init__.py
index 92637f9..a83b26a 100644
--- a/SPARQLWrapper/__init__.py
+++ b/SPARQLWrapper/__init__.py
@@ -1,6 +1,6 @@
 # -*- coding: utf8 -*-
 
-"""
+u"""
 
 This is a wrapper around a SPARQL service. It helps in creating the query URI and,
 possibly, convert the result into a more managable format.
@@ -163,28 +163,32 @@ The package was greatly inspired by U{Lee Feigenbaum's similar package for Javas
 @requires: U{RDFLib<http://rdflib.net>} package.
 """
 
-__version__ = "1.6.0"
+__version__ = "1.7.6"
 """The version of SPARQLWrapper"""
 
-__authors__  = u"Ivan Herman, Sergio Fernández, Carlos Tejo Alonso"
+__authors__  = "Ivan Herman, Sergio Fernández, Carlos Tejo Alonso, Alexey Zakhlestin"
 """The primary authors of SPARQLWrapper"""
 
-__license__ = u'W3C® SOFTWARE NOTICE AND LICENSE, http://www.w3.org/Consortium/Legal/copyright-software'
+__license__ = "W3C® SOFTWARE NOTICE AND LICENSE, http://www.w3.org/Consortium/Legal/copyright-software"
 """The license governing the use and distribution of SPARQLWrapper"""
 
-__url__ = 'http://sparql-wrapper.sourceforge.net/'
+__url__ = "http://rdflib.github.io/sparqlwrapper"
 """The URL for SPARQLWrapper's homepage"""
 
-__contact__ = 'sparql-wrapper-devel at lists.sourceforge.net'
-"""Mail list to contact to other people SPARQLWrappers folks and the developers"""
+__contact__ = "rdflib-dev at googlegroups.com"
+"""Mail list to contact to other people RDFLib and SPARQLWrappers folks and developers"""
 
-__date__    = "2012-08-28"
+__date__    = "2015-12-18"
 """Last update"""
 
-__agent__   = "sparqlwrapper %s (http://sparql-wrapper.sourceforge.net/)" % __version__
+__agent__   = "sparqlwrapper %s (rdflib.github.io/sparqlwrapper)" % __version__
 
 
-from Wrapper import SPARQLWrapper, XML, JSON, TURTLE, N3, JSONLD, RDF, GET, POST, SELECT, CONSTRUCT, ASK, DESCRIBE
-from Wrapper import INSERT, DELETE, MODIFY
-from SmartWrapper import SPARQLWrapper2
+from Wrapper import SPARQLWrapper
+from Wrapper import XML, JSON, TURTLE, N3, JSONLD, RDF
+from Wrapper import GET, POST
+from Wrapper import SELECT, CONSTRUCT, ASK, DESCRIBE, INSERT, DELETE
+from Wrapper import URLENCODED, POSTDIRECTLY
+from Wrapper import BASIC, DIGEST
 
+from SmartWrapper import SPARQLWrapper2
diff --git a/SPARQLWrapper/jsonlayer.py b/SPARQLWrapper/jsonlayer.py
deleted file mode 100644
index 00664a3..0000000
--- a/SPARQLWrapper/jsonlayer.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2009 Christopher Lenz
-# 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. The name of the author may not be used to endorse or promote
-# products derived from this software without specific prior
-# written permission.
-
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-
-"""Thin abstraction layer over the different available modules for decoding
-and encoding JSON data.
-
-This module currently supports the following JSON modules:
- - ``simplejson``: http://code.google.com/p/simplejson/
- - ``cjson``: http://pypi.python.org/pypi/python-cjson
- - ``json``: This is the version of ``simplejson`` that is bundled with the
-   Python standard library since version 2.6
-   (see http://docs.python.org/library/json.html)
-
-The default behavior is to use ``simplejson`` if installed, and otherwise
-fallback to the standard library module. To explicitly tell SPARQLWrapper
-which module to use, invoke the `use()` function with the module name::
-
-    import jsonlayer
-    jsonlayer.use('cjson')
-
-In addition to choosing one of the above modules, you can also configure
-SPARQLWrapper to use custom decoding and encoding functions::
-
-    import jsonlayer
-    jsonlayer.use(decode=my_decode, encode=my_encode)
-
-"""
-
-__all__ = ['decode', 'encode', 'use']
-
-_initialized = False
-_using = None
-_decode = None
-_encode = None
-
-
-def decode(string):
-    """Decode the given JSON string.
-   
-    :param string: the JSON string to decode
-    :type string: basestring
-    :return: the corresponding Python data structure
-    :rtype: object
-    """
-    if not _initialized:
-        _initialize()
-    return _decode(string)
-
-
-def encode(obj):
-    """Encode the given object as a JSON string.
-   
-    :param obj: the Python data structure to encode
-    :type obj: object
-    :return: the corresponding JSON string
-    :rtype: basestring
-    """
-    if not _initialized:
-        _initialize()
-    return _encode(obj)
-
-
-def use(module=None, decode=None, encode=None):
-    """Set the JSON library that should be used, either by specifying a known
-    module name, or by providing a decode and encode function.
-   
-    The modules "simplejson", "cjson", and "json" are currently supported for
-    the ``module`` parameter.
-   
-    If provided, the ``decode`` parameter must be a callable that accepts a
-    JSON string and returns a corresponding Python data structure. The
-    ``encode`` callable must accept a Python data structure and return the
-    corresponding JSON string. Exceptions raised by decoding and encoding
-    should be propagated up unaltered.
-   
-    :param module: the name of the JSON library module to use, or the module object itself
-    :type module: str or module
-    :param decode: a function for decoding JSON strings
-    :type decode: callable
-    :param encode: a function for encoding objects as JSON strings
-    :type encode: callable
-    """
-    global _decode, _encode, _initialized, _using
-    if module is not None:
-        if not isinstance(module, basestring):
-            module = module.__name__
-        if module not in ('cjson', 'json', 'simplejson'):
-            raise ValueError('Unsupported JSON module %s' % module)
-        _using = module
-        _initialized = False
-    else:
-        assert decode is not None and encode is not None
-        _using = 'custom'
-        _decode = decode
-        _encode = encode
-        _initialized = True
-
-
-def _initialize():
-    global _initialized
-
-    def _init_simplejson():
-        global _decode, _encode
-        import simplejson
-        _decode = lambda string, loads=simplejson.loads: loads(string)
-        _encode = lambda obj, dumps=simplejson.dumps: \
-            dumps(obj, allow_nan=False, ensure_ascii=False)
-
-    def _init_cjson():
-        global _decode, _encode
-        import cjson
-        _decode = lambda string, decode=cjson.decode: decode(string)
-        _encode = lambda obj, encode=cjson.encode: encode(obj)
-
-    def _init_stdlib():
-        global _decode, _encode
-        json = __import__('json', {}, {})
-        _decode = lambda string, loads=json.loads: loads(string)
-        _encode = lambda obj, dumps=json.dumps: \
-            dumps(obj, allow_nan=False, ensure_ascii=False)
-
-    if _using == 'simplejson':
-        _init_simplejson()
-    elif _using == 'cjson':
-        _init_cjson()
-    elif _using == 'json':
-        _init_stdlib()
-    elif _using != 'custom':
-        try:
-            _init_simplejson()
-        except ImportError:
-            _init_stdlib()
-    _initialized = True
-
-
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..cdd0693
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,2 @@
+rdflib>=4.0
+keepalive>=0.5
diff --git a/run_tests_py3.sh b/run_tests_py3.sh
new file mode 100755
index 0000000..c0d6ae4
--- /dev/null
+++ b/run_tests_py3.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+function cmdcheck() {
+    command -v $0 >/dev/null 2>&1 || { echo >&2 "ERROR: command $0 required but it's not installed; aborting..."; exit -1; }
+}
+
+cmdcheck python3
+
+PYTHON_VERSION=`python3 -c "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));sys.stdout.write(t)";`
+
+cmdcheck 2to3-$PYTHON_VERSION
+cmdcheck nosetests-$PYTHON_VERSION
+
+python3 setup.py build
+
+if [ -d build/py3_testing ]; then
... 579 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/sparqlwrapper.git



More information about the Python-modules-commits mailing list