diff --git a/.gitignore b/.gitignore index a259e91..9e003b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# Own environment +py2/ +py3/ +.pytest_cache /.tox ### JetBrains template # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio diff --git a/.travis.yml b/.travis.yml index 840be3e..68fcda4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,13 @@ language: python python: - - "2.6" - "2.7" + - "3.4" + - "3.6" - "pypy" # command to install dependencies install: - pip install -r requirements.txt - - pip install --upgrade pytest - - pip install --upgrade pytest-ordering + - pip install --upgrade setuptools pytest pytest-ordering - python setup.py install # command to run tests -script: py.test surf \ No newline at end of file +script: py.test surf diff --git a/requirements.txt b/requirements.txt index e59b474..6554c6f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ rdflib>=4.2.1 SPARQLWrapper>=1.7.6 -six>=1.10.0 \ No newline at end of file +six>=1.10.0 +future \ No newline at end of file diff --git a/setup.py b/setup.py index 29ed5ce..6ab1c29 100644 --- a/setup.py +++ b/setup.py @@ -64,6 +64,7 @@ deps = [ 'rdflib>=4.2.1', 'SPARQLWrapper>=1.7.6', + "future" ] test_deps = [ @@ -92,6 +93,7 @@ 'Operating System :: OS Independent', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.4', 'Topic :: Software Development :: Libraries :: Python Modules', ], keywords='Python SPARQL RDF resource mapper ORM query Semantic Web RDFS rdflib Object-Oriented', diff --git a/surf/__version__.py b/surf/__version__.py index 6688eb1..fc7bfcf 100644 --- a/surf/__version__.py +++ b/surf/__version__.py @@ -33,6 +33,7 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from builtins import map from collections import namedtuple __author__ = 'Cosmin Basca' diff --git a/surf/log.py b/surf/log.py index 0874c03..c45602d 100644 --- a/surf/log.py +++ b/surf/log.py @@ -30,6 +30,7 @@ # 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. +from past.builtins import basestring __author__ = 'Cosmin Basca' LOGGER_NAME = 'surf' diff --git a/surf/namespace.py b/surf/namespace.py index bd102ea..bed2235 100644 --- a/surf/namespace.py +++ b/surf/namespace.py @@ -1,3 +1,4 @@ +from builtins import str # Copyright (c) 2009, Digital Enterprise Research Institute (DERI), # NUI Galway # All rights reserved. @@ -34,6 +35,7 @@ # -*- coding: utf-8 -*- +from past.builtins import basestring __author__ = ['Cosmin Basca', 'Peteris Caune'] from copy import deepcopy @@ -114,14 +116,14 @@ # Fix for http://code.google.com/p/rdflib/issues/detail?id=154 def _unicode(namespace): - uri = unicode(namespace) + uri = str(namespace) if not isinstance(uri, basestring) and hasattr(namespace, 'uri'): - uri = unicode(namespace.uri) + uri = str(namespace.uri) return uri # an internal inverted dict - for fast access _INVERTED = {} -for k, v in sys.modules[__name__].__dict__.items(): +for k, v in list(sys.modules[__name__].__dict__.items()): if isinstance(v, (Namespace, ClosedNamespace)): if k == "_fallback_namespace": # no, this is not a namespace prefix, this is just a variable name @@ -129,7 +131,7 @@ def _unicode(namespace): _INVERTED[_unicode(v)] = k __DIRECT__ = {} -for k, v in sys.modules[__name__].__dict__.items(): +for k, v in list(sys.modules[__name__].__dict__.items()): if isinstance(v, (Namespace, ClosedNamespace)): __DIRECT__[k] = v @@ -193,7 +195,7 @@ def register(**namespaces): for key in namespaces: uri = namespaces[key] prefix = key.upper() - if not type(uri) in [Namespace, ClosedNamespace]: + if not isinstance(uri, (Namespace, ClosedNamespace)): uri = Namespace(uri) ns_dict[prefix] = uri @@ -242,7 +244,7 @@ def get_namespace(base): global _anonymous_count ns_dict = sys.modules[__name__].__dict__ - if not type(base) in [str, unicode]: + if not isinstance(base, (str, str)): base = str(base) try: diff --git a/surf/noconflict.py b/surf/noconflict.py index 1ddc358..260861e 100644 --- a/surf/noconflict.py +++ b/surf/noconflict.py @@ -5,7 +5,10 @@ # Recipe 204197: SOLVING THE METACLASS CONFLICT # http://code.activestate.com/recipes/204197/ -import inspect, types, __builtin__ +from future import standard_library +standard_library.install_aliases() +from builtins import map +import inspect, types, builtins ''' .. note:: This module appears `as is` and is based on the `Recipe 204197: @@ -27,7 +30,7 @@ def skip_redundant(iterable, skipset=None): def remove_redundant(metaclasses): - skipset = set([types.ClassType]) + skipset = set([type]) for meta in metaclasses: # determines the metaclasses to be skipped skipset.update(inspect.getmro(meta)[1:]) return tuple(skip_redundant(metaclasses, skipset)) diff --git a/surf/plugin/__init__.py b/surf/plugin/__init__.py index 9aa2cb7..8a43b25 100644 --- a/surf/plugin/__init__.py +++ b/surf/plugin/__init__.py @@ -33,19 +33,19 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from builtins import object from abc import ABCMeta import logging +from future.utils import with_metaclass __author__ = 'Cosmin Basca' -class Plugin(object): +class Plugin(with_metaclass(ABCMeta, object)): """ Super class for all SuRF plugins, provides basic instantiation and `logging`. """ - __metaclass__ = ABCMeta - def __init__(self, *args, **kwargs): super(Plugin, self).__init__() self._inference = False diff --git a/surf/plugin/manager.py b/surf/plugin/manager.py index 172b4cd..b01be97 100644 --- a/surf/plugin/manager.py +++ b/surf/plugin/manager.py @@ -123,7 +123,7 @@ def registered_readers(): :return: the registered reader plugins :rtype: list or set """ - return _readers.keys() + return list(_readers.keys()) def registered_writers(): @@ -133,7 +133,7 @@ def registered_writers(): :return: the registered writer plugins :rtype: list or set """ - return _writers.keys() + return list(_writers.keys()) def get_reader(reader_id, *args, **kwargs): diff --git a/surf/plugin/query_reader.py b/surf/plugin/query_reader.py index 654d59b..64619d5 100644 --- a/surf/plugin/query_reader.py +++ b/surf/plugin/query_reader.py @@ -33,6 +33,8 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from builtins import range +from past.builtins import basestring from abc import ABCMeta, abstractmethod from surf.plugin.reader import RDFReader @@ -40,6 +42,7 @@ from surf.query import a, ask, select, optional_group, named_group from surf.rdf import URIRef from surf.log import * +from future.utils import with_metaclass __author__ = 'Cosmin Basca' @@ -155,7 +158,7 @@ def order_terms(s, p, o): return (s, p, o) if direct else (o, p, s) for attribute, values, direct in params["get_by"]: - if hasattr(values, "__iter__"): + if not isinstance(values, basestring) and hasattr(values, "__iter__"): where_clause = Union() for value in values: where_clause.append(order_terms("?s", attribute, value)) @@ -190,17 +193,15 @@ def order_terms(s, p, o): return query -class RDFQueryReader(RDFReader): +class RDFQueryReader(with_metaclass(ABCMeta, RDFReader)): """ Super class for SuRF Reader plugins that wrap queryable `stores`. """ - __metaclass__ = ABCMeta - def __init__(self, *args, **kwargs): super(RDFQueryReader, self).__init__(*args, **kwargs) self.use_subqueries = kwargs.get('use_subqueries', False) - if isinstance(self.use_subqueries, str): + if isinstance(self.use_subqueries, basestring): self.use_subqueries = (self.use_subqueries.lower() == 'true') elif not isinstance(self.use_subqueries, bool): raise ValueError('The use_subqueries parameter must be a bool or a string set to "true" or "false"') @@ -244,7 +245,7 @@ def _get_by(self, params): query.optional_group(("?s", a, "?c")) context = params.get("context", None) - if not (context is None): + if context is not None: query.from_(context) # Load just subjects and their types diff --git a/surf/plugin/rdflib/reader.py b/surf/plugin/rdflib/reader.py index 59a09b4..4bb7c2c 100755 --- a/surf/plugin/rdflib/reader.py +++ b/surf/plugin/rdflib/reader.py @@ -1,3 +1,4 @@ +from builtins import str # Copyright (c) 2009, Digital Enterprise Research Institute (DERI), # NUI Galway # All rights reserved. @@ -34,9 +35,10 @@ # -*- coding: utf-8 -*- +from builtins import zip try: from json import loads -except ImportError, e: +except ImportError as e: from simplejson import loads from surf.plugin.query_reader import RDFQueryReader from surf.rdf import ConjunctiveGraph @@ -79,17 +81,17 @@ def _to_table(self, result): # Elements in result.selectionF are instances of rdflib.Variable, # rdflib.Variable is subclass of unicode. We convert them to # unicode here anyway to hide rdflib internals from clients. - vars = [unicode(var) for var in result.vars] + vars = [str(var) for var in result.vars] # Convert each row to dict: { var->value, ... } - return [dict(zip(vars, row)) for row in result] + return [dict(list(zip(vars, row))) for row in result] def _ask(self, result): # askAnswer is list with boolean values, we want first value. return result.askAnswer[0] def _execute(self, query): - q_string = unicode(query) + q_string = str(query) debug(q_string) return self._graph.query(q_string) diff --git a/surf/plugin/rdflib/writer.py b/surf/plugin/rdflib/writer.py index eb00040..e6c527f 100644 --- a/surf/plugin/rdflib/writer.py +++ b/surf/plugin/rdflib/writer.py @@ -84,7 +84,7 @@ def _save(self, *resources): for resource in resources: s = resource.subject self._remove_from_graph(s) - for p, objs in resource.rdf_direct.items(): + for p, objs in list(resource.rdf_direct.items()): for o in objs: self.__add(s, p, o) @@ -95,7 +95,7 @@ def _update(self, *resources): s = resource.subject for p in resource.rdf_direct: self._remove_from_graph(s, p) - for p, objs in resource.rdf_direct.items(): + for p, objs in list(resource.rdf_direct.items()): for o in objs: self.__add(s, p, o) diff --git a/surf/plugin/reader.py b/surf/plugin/reader.py index c41e631..01e60f0 100644 --- a/surf/plugin/reader.py +++ b/surf/plugin/reader.py @@ -36,17 +36,16 @@ from abc import ABCMeta, abstractmethod from surf.plugin import Plugin +from future.utils import with_metaclass __author__ = 'Cosmin Basca' -class RDFReader(Plugin): +class RDFReader(with_metaclass(ABCMeta, Plugin)): """ Super class for all surf Reader plugins. """ - __metaclass__ = ABCMeta - @abstractmethod def _get(self, subject, attribute, direct, context): """ diff --git a/surf/plugin/sparql_protocol/reader.py b/surf/plugin/sparql_protocol/reader.py index 705933e..1ba7376 100644 --- a/surf/plugin/sparql_protocol/reader.py +++ b/surf/plugin/sparql_protocol/reader.py @@ -1,3 +1,4 @@ +from builtins import str # Copyright (c) 2009, Digital Enterprise Research Institute (DERI), # NUI Galway # All rights reserved. @@ -33,6 +34,7 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from future.utils import raise_ __author__ = 'Cosmin Basca' import sys @@ -83,7 +85,7 @@ def _to_table(self, result): converted = [] for binding in result["results"]["bindings"]: rdf_item = {} - for key, obj in binding.items(): + for key, obj in list(binding.items()): try: rdf_item[key] = json_to_rdflib(obj) except ValueError: @@ -103,15 +105,15 @@ def execute_sparql(self, q_string, format='JSON'): debug(q_string) self._sparql_wrapper.setQuery(q_string) return self._sparql_wrapper.query().convert() - except EndPointNotFound, _: - raise SparqlReaderException("Endpoint not found"), None, sys.exc_info()[2] - except QueryBadFormed, _: - raise SparqlReaderException("Bad query: %s" % q_string), None, sys.exc_info()[2] - except Exception, e: - raise SparqlReaderException("Exception: %s" % e), None, sys.exc_info()[2] + except EndPointNotFound as _: + raise_(SparqlReaderException, "Endpoint not found", sys.exc_info()[2]) + except QueryBadFormed as _: + raise_(SparqlReaderException, "Bad query: %s" % q_string, sys.exc_info()[2]) + except Exception as e: + raise_(SparqlReaderException, "Exception: %s" % e, sys.exc_info()[2]) def _execute(self, query): - return self.execute_sparql(unicode(query)) + return self.execute_sparql(str(query)) def close(self): pass diff --git a/surf/plugin/sparql_protocol/writer.py b/surf/plugin/sparql_protocol/writer.py index c98f5ef..cef13b3 100644 --- a/surf/plugin/sparql_protocol/writer.py +++ b/surf/plugin/sparql_protocol/writer.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import # Copyright (c) 2009, Digital Enterprise Research Institute (DERI), # NUI Galway # All rights reserved. @@ -31,6 +32,8 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from builtins import str +from future.utils import raise_ __author__ = 'Cosmin Basca, Adam Gzella' import sys @@ -38,7 +41,7 @@ from SPARQLWrapper import SPARQLWrapper, JSON from SPARQLWrapper.SPARQLExceptions import EndPointNotFound, QueryBadFormed, SPARQLWrapperException -from reader import ReaderPlugin +from .reader import ReaderPlugin from surf.plugin.writer import RDFWriter from surf.query import Filter, Group, NamedGroup, Union from surf.query.update import insert, delete, clear, load @@ -67,7 +70,7 @@ def _prepare_add_many_query(resources, context=None): for resource in resources: s = resource.subject - for p, objs in resource.rdf_direct.items(): + for p, objs in list(resource.rdf_direct.items()): for o in objs: query.template((s, p, o)) @@ -152,21 +155,21 @@ def endpoint(self): return self._endpoint def _save(self, *resources): - for context, items in _group_by_context(resources).iteritems(): + for context, items in _group_by_context(resources).items(): # Deletes all triples with matching subjects. remove_query = _prepare_delete_many_query(items, context) insert_query = _prepare_add_many_query(items, context) self._execute(remove_query, insert_query) def _update(self, *resources): - for context, items in _group_by_context(resources).iteritems(): + for context, items in _group_by_context(resources).items(): # Explicitly enumerates triples for deletion. remove_query = _prepare_selective_delete_query(items, context) insert_query = _prepare_add_many_query(items, context) self._execute(remove_query, insert_query) def _remove(self, *resources, **kwargs): - for context, items in _group_by_context(resources).iteritems(): + for context, items in _group_by_context(resources).items(): # Deletes all triples with matching subjects. inverse = kwargs.get("inverse") query = _prepare_delete_many_query(items, context, inverse) @@ -189,7 +192,7 @@ def _remove_triple(self, s=None, p=None, o=None, context=None): def _execute(self, *queries): """ Execute several queries. """ - translated = [unicode(query) for query in queries] + translated = [str(query) for query in queries] if self._combine_queries: translated = ["\n".join(translated)] @@ -202,13 +205,13 @@ def _execute(self, *queries): return True - except EndPointNotFound, _: - raise SparqlWriterException("Endpoint not found"), None, sys.exc_info()[2] - except QueryBadFormed, _: - raise SparqlWriterException("Bad query: %s" % query_str), None, sys.exc_info()[2] - except Exception, e: + except EndPointNotFound as _: + raise_(SparqlWriterException, "Endpoint not found", sys.exc_info()[2]) + except QueryBadFormed as _: + raise_(SparqlWriterException, "Bad query: %s" % query_str, sys.exc_info()[2]) + except Exception as e: msg = "Exception: %s (query: %s)" % (e, query_str) - raise SparqlWriterException(msg), None, sys.exc_info()[2] + raise_(SparqlWriterException, msg, sys.exc_info()[2]) def _add_many(self, triples, context=None): debug("ADD several triples") @@ -220,19 +223,19 @@ def _add_many(self, triples, context=None): for s, p, o in triples: query.template((s, p, o)) - query_str = unicode(query) + query_str = str(query) try: debug(query_str) self._sparql_wrapper.setQuery(query_str) self._sparql_wrapper.query().convert() return True - except EndPointNotFound, _: - raise SparqlWriterException("Endpoint not found"), None, sys.exc_info()[2] - except QueryBadFormed, _: - raise SparqlWriterException("Bad query: %s" % query_str), None, sys.exc_info()[2] - except Exception, e: - raise SparqlWriterException("Exception: %s" % e), None, sys.exc_info()[2] + except EndPointNotFound as _: + raise_(SparqlWriterException, "Endpoint not found", sys.exc_info()[2]) + except QueryBadFormed as _: + raise_(SparqlWriterException, "Bad query: %s" % query_str, sys.exc_info()[2]) + except Exception as e: + raise_(SparqlWriterException, "Exception: %s" % e, sys.exc_info()[2]) def _add(self, s, p, o, context=None): return self._add_many([(s, p, o)], context) @@ -260,16 +263,16 @@ def _remove_from_endpoint(self, s=None, p=None, o=None, context=None): where_group.append(filter) query.where(where_group) - query_str = unicode(query) + query_str = str(query) debug(query_str) self._sparql_wrapper.setQuery(query_str) self._sparql_wrapper.query().convert() return True - except EndPointNotFound, _: + except EndPointNotFound as _: error("SPARQL endpoint not found") - except QueryBadFormed, _: + except QueryBadFormed as _: error("Bad-formed SPARQL query") - except SPARQLWrapperException, _: + except SPARQLWrapperException as _: error("SPARQLWrapper exception") return None @@ -307,7 +310,7 @@ def load_triples(self, source=None, context=None): if context: query.into(context) - query_str = unicode(query) + query_str = str(query) debug(query_str) self._sparql_wrapper.setQuery(query_str) self._sparql_wrapper.query().convert() @@ -322,9 +325,9 @@ def _clear(self, context=None): self._remove_from_endpoint(None, None, None, context=context) def _term(self, term): - if type(term) in [URIRef, BNode]: + if isinstance(term, (URIRef, BNode)): return u'{0:s}'.format - elif type(term) in [str, unicode]: + elif isinstance(term, (str, str)): if term.startswith('?'): return u'{0:s}'.format(term) elif is_uri(term): @@ -333,7 +336,7 @@ def _term(self, term): return u'"{0:s}"'.format(term) elif type(term) is Literal: return term.n3() - elif type(term) in [list, tuple]: + elif isinstance(term, (list, tuple)): return '"{0:s}"@{1:s}'.format(term[0], term[1]) elif type(term) is type and hasattr(term, 'uri'): return u'{0:s}'.format diff --git a/surf/plugin/writer.py b/surf/plugin/writer.py index 025531e..a60b471 100644 --- a/surf/plugin/writer.py +++ b/surf/plugin/writer.py @@ -37,6 +37,7 @@ from surf.plugin import Plugin from surf.plugin.reader import RDFReader +from future.utils import with_metaclass __author__ = 'Cosmin Basca' @@ -46,13 +47,11 @@ def __init__(self,*args,**kwargs): super(InvalidResourceException,self).__init__(self,*args,**kwargs) -class RDFWriter(Plugin): +class RDFWriter(with_metaclass(ABCMeta, Plugin)): """ Super class for all surf Writer plugins. """ - __metaclass__ = ABCMeta - def __init__(self, reader, *args, **kwargs): super(RDFWriter, self).__init__(*args, **kwargs) if isinstance(reader,RDFReader): diff --git a/surf/query/__init__.py b/surf/query/__init__.py index fa90234..0e5b7b4 100644 --- a/surf/query/__init__.py +++ b/surf/query/__init__.py @@ -33,6 +33,12 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from builtins import object +from builtins import str +from past.builtins import basestring +import sys +_py_version = sys.version_info[0] + from surf.rdf import BNode, Graph, ConjunctiveGraph, Literal, Namespace from surf.rdf import RDF, URIRef import re @@ -64,7 +70,7 @@ class NamedGroup(Group): """ def __init__(self, name = None): super(NamedGroup, self).__init__() - if isinstance(name, URIRef) or (type(name) in [str, unicode] and name.startswith('?')): + if isinstance(name, URIRef) or (isinstance(name, str) and name.startswith('?')): self.name = name else: raise ValueError("Invalid specifier for named group" @@ -84,18 +90,18 @@ class Union(Group): """ -class Filter(unicode): +class Filter(str): """ A **SPARQL** triple pattern filter """ @classmethod def regex(cls, var, pattern, flag=None): - if isinstance(var, (str, unicode)) and var.startswith('?'): + if isinstance(var, basestring) and var.startswith('?'): pass else: raise ValueError('not a filter variable') - if isinstance(pattern, (str, unicode)): + if isinstance(pattern, basestring): pass elif isinstance(pattern, Literal): pattern = '"{0:s}"@{1:s}'.format(pattern, pattern.language) @@ -107,14 +113,14 @@ def regex(cls, var, pattern, flag=None): if flag is None: flag = "" else: - if not isinstance(flag, (str, unicode)): + if not isinstance(flag, basestring): raise ValueError('not a filter flag') return Filter('regex({0:s},"{1:s}"{2:s})'.format(var, pattern, u',"{0:s}"'.format(flag))) def _validate_variable(variable): - if isinstance(variable, (str, unicode)): + if isinstance(variable, basestring): if variable.startswith('?'): return True elif re.match('\s*\(\s*.+\s+AS\s+\?.+\)\s*$', variable): @@ -128,6 +134,7 @@ def _validate_variable(variable): expression, or supported aggregate %s)''' % (variable, str(Query.AGGREGATE_FUNCTIONS))) else: + print(variable, type(variable), str.__name__) raise ValueError('''Unknown variable type, all variables must either start with a "?" or be among the recognized aggregates : %s''' % Query.AGGREGATE_FUNCTIONS) @@ -349,9 +356,10 @@ def filter(self, filter): if not filter: return self - elif type(filter) in [str, unicode]: + elif isinstance(filter, basestring): filter = Filter(filter) - elif type(filter) is not Filter: + elif not isinstance(filter, Filter): + print(type(filter)) raise ValueError('the filter must be of type Filter, str or unicode following the syntax of the query language') self._data.append(filter) return self @@ -383,35 +391,45 @@ def order_by(self, *variables): return self - def __unicode__(self): + def _unicode(self): # Importing here to avoid circular imports. from surf.query.translator.sparql import SparqlTranslator return SparqlTranslator(self).translate() + def __unicode__(self): + return self._unicode() + def __str__(self): - return unicode(self).encode("utf-8") + if _py_version == 3: + return self._unicode() + else: + return str(self._unicode()).encode("utf-8") def validate_statement(statement): if isinstance(statement, tuple(Query.STATEMENT_TYPES + [Query])): - if isinstance(statement, (list, tuple)): + # since `NamedGroup` inherits from `list` via `Group` here we want + # to use `type()` instead of `isinstance()` as we need to tell + # whether `statement` is e.g. a list/tuple or an instance of + # `NamedGroup` + if type(statement) in [list, tuple]: try: s, p, o = statement except: raise ValueError('''Statement of type [list, tuple] does not have all the (s,p,o) members (the length of the supplied arguemnt must be at least 3)''') - if isinstance(s, (URIRef, BNode)) or (isinstance(s, (str, unicode)) and s.startswith('?')): + if isinstance(s, (URIRef, BNode)) or (isinstance(s, basestring) and s.startswith('?')): pass else: raise ValueError('The subject is not a valid variable type') - if isinstance(p, URIRef) or (isinstance(p, (str, unicode)) and p.startswith('?')): + if isinstance(p, URIRef) or (isinstance(p, basestring) and p.startswith('?')): pass else: raise ValueError('The predicate is not a valid variable type') - if isinstance(o, (URIRef, BNode, Literal)) or (isinstance(o, (str, unicode)) and o.startswith('?')): + if isinstance(o, (URIRef, BNode, Literal)) or (isinstance(o, basestring) and o.startswith('?')): pass else: raise ValueError(u'The object is not a valid variable type: {0:s}'.format(o)) diff --git a/surf/query/translator/__init__.py b/surf/query/translator/__init__.py index e7d638d..72feb35 100644 --- a/surf/query/translator/__init__.py +++ b/surf/query/translator/__init__.py @@ -33,6 +33,7 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from builtins import object __author__ = 'Cosmin Basca' from surf.query import Query diff --git a/surf/query/translator/sparql.py b/surf/query/translator/sparql.py index bba667e..d6346bf 100644 --- a/surf/query/translator/sparql.py +++ b/surf/query/translator/sparql.py @@ -91,9 +91,9 @@ def _translate_ask(self, query): 'where' : where, }) def _term(self, term): - if type(term) in [URIRef, BNode]: + if isinstance(term, (URIRef, BNode)): return '%s' % (term.n3()) - elif type(term) in [str, unicode]: + elif isinstance(term, str): if term.startswith('?'): return '%s' % term elif is_uri(term): @@ -102,7 +102,7 @@ def _term(self, term): return '"%s"' % term elif type(term) is Literal: return term.n3() - elif type(term) in [list, tuple]: + elif isinstance(term, (list, tuple)): return '"%s"@%s' % (term[0], term[1]) elif type(term) is type and hasattr(term, 'uri'): return '%s' % term.uri().n3() @@ -135,9 +135,7 @@ def _subquery(self, stmt): return ' { %s } ' % (SparqlTranslator(stmt).translate()) def _statement(self, statement): - if type(statement) in [list, tuple]: - return self._triple_pattern(statement) - elif type(statement) is Group: + if type(statement) is Group: return self._group(statement) elif type(statement) is NamedGroup: return self._named_group(statement) @@ -149,3 +147,6 @@ def _statement(self, statement): return self._filter(statement) elif type(statement) is Query: return self._subquery(statement) + elif isinstance(statement, (list, tuple)): + # Moved this at the bottom because other classes are list/tuple desc + return self._triple_pattern(statement) diff --git a/surf/query/update.py b/surf/query/update.py index 4b396f0..0b60f97 100644 --- a/surf/query/update.py +++ b/surf/query/update.py @@ -120,7 +120,7 @@ def graph(self, uri): self._clear_uri = uri return self - def __unicode__(self): + def _unicode(self): # Importing here to avoid circular imports. from surf.query.translator.sparul import SparulTranslator return SparulTranslator(self).translate() diff --git a/surf/resource/__init__.py b/surf/resource/__init__.py index c34afec..0cbaca6 100644 --- a/surf/resource/__init__.py +++ b/surf/resource/__init__.py @@ -1,3 +1,4 @@ +from builtins import str # Copyright (c) 2009, Digital Enterprise Research Institute (DERI), # NUI Galway # All rights reserved. @@ -33,6 +34,9 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- + +from builtins import map +from builtins import object from surf.namespace import get_namespace_url, get_prefix, OWL, all, RDF_TYPE from surf.rdf import BNode, ClosedNamespace, ConjunctiveGraph, Graph, Literal from surf.rdf import Namespace, RDF, RDFS, URIRef @@ -43,6 +47,7 @@ from surf.util import attr2rdf, namespace_split, rdf2attr from surf.util import uri_to_class, uuid_subject, value_to_rdf from collections import defaultdict +from future.utils import with_metaclass __author__ = 'Cosmin Basca' @@ -96,7 +101,7 @@ def __getattr__(self, attr_name): return getattr(self_as_instance, attr_name) -class Resource(object): +class Resource(with_metaclass(ResourceMeta, object)): """ The Resource class, represents the transparent proxy object that exposes sets of RDF triples under the form of and as an object @@ -164,8 +169,6 @@ class Resource(object): [rdflib.URIRef('http://p1'), ] """ - - __metaclass__ = ResourceMeta _dirty_instances = set() def __init__(self, subject = None, block_auto_load = False, context = None, @@ -185,7 +188,7 @@ def __init__(self, subject = None, block_auto_load = False, context = None, if subject is None: subject = uuid_subject(namespace) - elif not type(subject) in [URIRef, BNode]: + elif not isinstance(subject, (URIRef, BNode)): subject = URIRef(subject) self.__subject = subject @@ -193,14 +196,15 @@ def __init__(self, subject = None, block_auto_load = False, context = None, if context == NO_CONTEXT: self.__context = None elif context: - self.__context = URIRef(unicode(context)) + self.__context = URIRef(str(context)) elif self.session and self.store_key: self.__context = self.session[self.store_key].default_context self.__expired = False self.__rdf_direct = defaultdict(list) - self.__rdf_direct[RDF_TYPE].append(self.uri) self.__rdf_inverse = defaultdict(list) + self.rdf_type = self.uri + self.dirty = False # Reset dirty flag, which was automatically set in previous command self.__namespaces = all() # __full_direct and __full_inverse are set to true after doing full load. @@ -313,7 +317,7 @@ def _instance(cls, subject, uris, context = None, store = None, block_auto_load # uris might be an iterator, but we want each # element from it as separate argument, so # converting to list. - classes = map(uri_to_class, list(uris[1:])) + classes = list(map(uri_to_class, list(uris[1:]))) return cls.session.map_instance(uri, subject, classes = classes, block_auto_load = block_auto_load, @@ -334,7 +338,7 @@ def _lazy(cls, value): inst = r if isinstance(value[r], Resource) : inst = value[r] - elif type(r) in [URIRef, BNode]: + elif isinstance(r, (URIRef, BNode)): inst = cls._instance(r, value[r]) attr_value.append(inst) return attr_value @@ -347,9 +351,9 @@ def bind_namespaces(self, *namespaces): """ for ns in namespaces: - if type(ns) in [str, unicode]: + if isinstance(ns, str): self.__namespaces[ns] = get_namespace_url(ns) - elif type(ns) in [Namespace, ClosedNamespace]: + elif isinstance(ns, (Namespace, ClosedNamespace)): self.__namespaces[get_prefix(ns)] = ns def bind_namespaces_to_graph(self, graph): @@ -413,7 +417,7 @@ def getvalues_callable(): else: if type(value) not in [list, tuple]: value = [value] - value = map(value_to_rdf, value) + value = list(map(value_to_rdf, value)) getvalues_callable = prepare_getvalues_callable(value, rdf_dict[predicate]) value = LazyResourceLoader(getvalues_callable, self, name) @@ -561,7 +565,7 @@ def __set_predicate_values(self, results, direct): """ - for p, v in results.items(): + for p, v in list(results.items()): attr = rdf2attr(p, direct) value = self._lazy(v) if value: @@ -591,7 +595,7 @@ def get_by_attribute(cls, attributes, context = None): subjects.update(cls.session[cls.store_key].instances_by_attribute(cls, inverse_attributes, False, context)) instances = [] - for s, types in subjects.items(): + for s, types in list(subjects.items()): if not isinstance(s, URIRef): continue @@ -628,7 +632,7 @@ def __instance_factory(cls, params, instance_data): # In results? if (not _rdf_type and "direct" in data and RDF_TYPE in data["direct"] and data["direct"][RDF_TYPE]): - _rdf_type = data["direct"][RDF_TYPE].keys()[0] + _rdf_type = list(data["direct"][RDF_TYPE].keys())[0] if _rdf_type is None: # We don't know rdf:type, so cannot instantiate Resource, @@ -743,19 +747,19 @@ def graph(self, direct = True): graph.add((self.subject, RDF['type'], self.uri)) for predicate in self.__rdf_direct: for value in self.__rdf_direct[predicate]: - if type(value) in [URIRef, Literal, BNode]: + if isinstance(value, (URIRef, Literal, BNode)): graph.add((self.subject, predicate, value)) if not direct: for predicate in self.__rdf_inverse: for value in self.__rdf_inverse[predicate]: - if type(value) in [URIRef, Literal, BNode]: + if isinstance(value, (URIRef, Literal, BNode)): graph.add((value, predicate, self.subject)) return graph def __str__(self): """ Return `string` representation of the resource. """ - return '{%s : %s}' % (unicode(self.subject), unicode(self.uri)) + return '{%s : %s}' % (str(self.subject), str(self.uri)) def save(self): """ Save the `resource` to the data `store`. """ @@ -824,11 +828,11 @@ def set(self, graph): for s, p, o in graph: attr_name = None value = None - if unicode(s) == unicode(self.subject): + if str(s) == str(self.subject): attr_name = rdf2attr(p, True) #value = self.__lazy([o]) value = o - elif unicode(o) == unicode(self.subject): + elif str(o) == str(self.subject): attr_name = rdf2attr(p, False) #value = self.__lazy([s]) value = s diff --git a/surf/resource/lazy.py b/surf/resource/lazy.py index f73e4ad..c07dd38 100644 --- a/surf/resource/lazy.py +++ b/surf/resource/lazy.py @@ -64,10 +64,11 @@ def __init__(self, getvalues_callable, resource, attribute_name): # For lazy loading list contents self.__getvalues = getvalues_callable self.__data_loaded = False + self.__rdf_values = {} def __prepare_values(self): if not self.__data_loaded: - self[:], self.__rdf_values = self.__getvalues() + self[:], self.__rdf_values = self.__getvalues() self.__data_loaded = True def get_one(self): @@ -124,10 +125,11 @@ def __getitem__(self, key): return list.__getitem__(self, key) def __setitem__(self, key, value): - self.__prepare_values() + if key != slice(None, None, None): + self.__prepare_values() - self.set_dirty(True) - self.__rdf_values[key] = self.to_rdf(value) + self.set_dirty(True) + self.__rdf_values[key] = self.to_rdf(value) return list.__setitem__(self, key, value) def __delitem__(self, key): diff --git a/surf/resource/result_proxy.py b/surf/resource/result_proxy.py index 3ed5941..4a4904a 100644 --- a/surf/resource/result_proxy.py +++ b/surf/resource/result_proxy.py @@ -1,5 +1,6 @@ """ Module for ResultProxy. """ - +from past.builtins import basestring +from builtins import object from surf.exceptions import NoResultFound, MultipleResultsFound from surf.rdf import Literal from surf.util import attr2rdf, value_to_rdf @@ -145,12 +146,11 @@ def get_by(self, **kwargs): # If value has a subject attribute, this must be a Resource, # take its subject. value = value.subject - elif hasattr(value, "__iter__"): + elif not isinstance(value, basestring) and hasattr(value, "__iter__"): # Map alternatives - value = map(lambda val: hasattr(val, "subject") + value = [hasattr(val, "subject") and val.subject - or value_to_rdf(val), - value) + or value_to_rdf(val) for val in value] else: value = value_to_rdf(value) @@ -187,11 +187,11 @@ def filter(self, **kwargs): params = self._params.copy() params.setdefault("filter", []) - for name, value in kwargs.items(): + for name, value in list(kwargs.items()): attr, direct = attr2rdf(name) assert direct, "Only direct attributes can be used for filters" # Assume by plain strings user means literals - if type(value) in [str, unicode]: + if isinstance(value, str): value = Literal(value) params["filter"].append((attr, value, direct)) return ResultProxy(params) @@ -240,7 +240,7 @@ def first(self): item = None try: - item = iter(self).next() + item = next(iter(self)) except StopIteration: pass @@ -258,12 +258,12 @@ def one(self): iterator = iter(self) try: - item = iterator.next() + item = next(iterator) except StopIteration: raise NoResultFound("List is empty") try: - iterator.next() + next(iterator) except StopIteration: # As expected, return item return item diff --git a/surf/rest.py b/surf/rest.py index 50d76dc..9c0e887 100644 --- a/surf/rest.py +++ b/surf/rest.py @@ -33,6 +33,7 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from builtins import object import inspect from surf.rdf import Namespace from surf.resource import Resource diff --git a/surf/serializer.py b/surf/serializer.py index f5ae413..d54d187 100644 --- a/surf/serializer.py +++ b/surf/serializer.py @@ -1,3 +1,4 @@ +from builtins import str # Copyright (c) 2009, Digital Enterprise Research Institute (DERI), # NUI Galway # All rights reserved. @@ -38,7 +39,7 @@ try: from json import dumps -except ImportError, e: +except ImportError as e: from simplejson import dumps from surf.rdf import BNode, Literal, URIRef @@ -80,12 +81,12 @@ def to_json(graph): for v in graph.objects(s,p): value = {'value': v, 'type': value_types[type(v)]} if type(v) is Literal and v.language: - value['lang'] = unicode(v.language) + value['lang'] = str(v.language) if type(v) is Literal and v.datatype: - value['datatype'] = unicode(v.datatype) + value['datatype'] = str(v.datatype) json_values.append(value) - json_subjects[unicode(p)] = json_values - json_root[unicode(s)] = json_subjects + json_subjects[str(p)] = json_values + json_root[str(s)] = json_subjects return dumps(json_root) diff --git a/surf/session.py b/surf/session.py index dee9c2c..4083566 100644 --- a/surf/session.py +++ b/surf/session.py @@ -33,6 +33,14 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from builtins import str +from builtins import object +try: + # Python 2 + from __builtin__ import str as builtin_str +except ImportError: + # Python 3 + from builtins import str as builtin_str __author__ = 'Cosmin Basca' from surf.rdf import BNode, URIRef @@ -118,7 +126,7 @@ def __iter__(self): return self._stores.__iter__() def __reversed__(self): - return self._stores.items().__reversed__() + return list(self._stores.items()).__reversed__() def __contains__(self, item): """ True if the `item` is contained within the managed `stores`. """ @@ -126,7 +134,7 @@ def __contains__(self, item): def keys(self): """ The `keys` that are assigned to the managed `stores`. """ - return self._stores.keys() + return list(self._stores.keys()) @property def auto_persist(self): @@ -160,11 +168,11 @@ def auto_load(self, val): @property def log_level(self): - return dict((sid, store.log_level) for sid, store in self._stores.iteritems()) + return dict((sid, store.log_level) for sid, store in self._stores.items()) @log_level.setter def log_level(self, level): - for sid, store in self._stores.iteritems(): + for sid, store in self._stores.items(): store.log_level = level # TODO: add caching ... need strategies @@ -192,7 +200,7 @@ def default_store_key(self): if DEFAULT_STORE_KEY in self._stores: return DEFAULT_STORE_KEY elif len(self._stores) > 0: - return self._stores.keys()[0] + return list(self._stores.keys())[0] return None @property @@ -236,7 +244,7 @@ def close(self): """ - for store in self._stores.keys(): + for store in list(self._stores.keys()): self._stores[store].close() del self._stores[store] @@ -265,7 +273,8 @@ def map_type(self, uri, store=None, classes=None): if type(session_classes) not in [list, tuple, set]: session_classes = [session_classes] base_classes.extend(session_classes) - return type(str(name), tuple(base_classes), {'uri': uri, + + return type(builtin_str(name), tuple(base_classes), {'uri': uri, 'store_key': store, 'session': self}) @@ -292,8 +301,8 @@ def map_instance(self, concept, subject, store=None, classes=None, classes = classes if isinstance(classes, (tuple, set, list)) else [] - if not type(subject) in [URIRef, BNode]: - subject = URIRef(unicode(subject)) + if not isinstance(subject, (URIRef, BNode)): + subject = URIRef(str(subject)) if not store: store = self.default_store_key @@ -310,7 +319,7 @@ def get_resource(self, subject, concept=None, store=None, graph=None, classes = classes if isinstance(classes, (tuple, set, list)) else [] if not isinstance(subject, URIRef): - subject = URIRef(unicode(subject)) + subject = URIRef(str(subject)) if concept is None: concept = Resource.concept(subject) diff --git a/surf/store.py b/surf/store.py index a0642e2..91a7d1e 100644 --- a/surf/store.py +++ b/surf/store.py @@ -33,12 +33,14 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from builtins import object from surf.log import * from surf.plugin.manager import load_plugins, get_reader, get_writer from surf.plugin.reader import RDFReader, NoneReader from surf.plugin.writer import RDFWriter, NoneWriter from surf.query import Query from surf.rdf import URIRef +from surf.util import error_message __author__ = 'Cosmin Basca' @@ -108,14 +110,14 @@ def close(self): try: self.reader.close() debug('reader closed successfully') - except Exception, e: - error("Error on closing the reader: %s", e.message) + except Exception as e: + error("Error on closing the reader: %s", error_message(e)) try: self.writer.close() debug('writer closed successfully') - except Exception, e: - error("Error on closing the writer: %s", e.message) + except Exception as e: + error("Error on closing the writer: %s", error_message(e)) def get(self, resource, attribute, direct): """ :func:`surf.plugin.reader.RDFReader.get` method. """ @@ -160,7 +162,7 @@ def execute(self, query): def execute_sparql(self, sparql_query, format = 'JSON'): """see :meth:`surf.plugin.query_reader.RDFQueryReader.execute_sparql` method. """ - if hasattr(self.reader, 'execute_sparql') and type(sparql_query) in [str, unicode]: + if hasattr(self.reader, 'execute_sparql') and isinstance(sparql_query, str): return self.reader.execute_sparql(sparql_query, format = format) return None diff --git a/surf/test/plugin/test_query_reader.py b/surf/test/plugin/test_query_reader.py index 57b3af4..fd6029b 100644 --- a/surf/test/plugin/test_query_reader.py +++ b/surf/test/plugin/test_query_reader.py @@ -3,6 +3,7 @@ import logging import warnings from surf.plugin.query_reader import RDFQueryReader +from surf.util import error_message def test_convert_unicode_exception(): @@ -28,5 +29,5 @@ def _to_table(self, _): logging.disable(logging.ERROR) MyQueryReader().convert(None) logging.disable(logging.NOTSET) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) diff --git a/surf/test/plugin/test_rdflib.py b/surf/test/plugin/test_rdflib.py index 37f446d..01592bc 100644 --- a/surf/test/plugin/test_rdflib.py +++ b/surf/test/plugin/test_rdflib.py @@ -1,7 +1,10 @@ +from __future__ import print_function import pytest import surf import os from rdflib.term import Literal +from surf.util import error_message + _card_file = os.path.join(os.path.split(os.path.abspath(__file__))[0], 'card.rdf') @@ -22,8 +25,8 @@ def test_rdflib_store(): # clean store store.clear() - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_rdflib_load(): @@ -31,7 +34,7 @@ def test_rdflib_load(): writer="rdflib", rdflib_store="IOMemory") - print "Load RDF data" + print("Load RDF data") store.load_triples(source=_card_file) assert len(store) == 76 diff --git a/surf/test/plugin/test_sparql_protocol.py b/surf/test/plugin/test_sparql_protocol.py index b0adb85..459281d 100644 --- a/surf/test/plugin/test_sparql_protocol.py +++ b/surf/test/plugin/test_sparql_protocol.py @@ -1,9 +1,11 @@ # -*- coding: UTF-8 -*- +from builtins import str import pytest import surf from surf.query import select from surf.rdf import Literal, URIRef from surf.exceptions import CardinalityException +from surf.util import error_message from surf.plugin.sparql_protocol.reader import SparqlReaderException from surf.plugin.sparql_protocol.writer import SparqlWriterException @@ -46,8 +48,8 @@ def test_to_table(): try: store = surf.store.Store(reader="sparql_protocol") store.reader._to_table(data) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_exceptions(): diff --git a/surf/test/query/test_sparql.py b/surf/test/query/test_sparql.py index b177152..2c225d6 100644 --- a/surf/test/query/test_sparql.py +++ b/surf/test/query/test_sparql.py @@ -1,3 +1,5 @@ +from builtins import str +from past.builtins import basestring import pytest import re @@ -14,7 +16,7 @@ def canonical(sparql_string): capitalization differences. """ - assert(isinstance(sparql_string, unicode)) + assert(isinstance(sparql_string, basestring)) result = sparql_string.strip().lower() result = re.sub("\s\s+", " ", result) @@ -46,7 +48,7 @@ def test_simple(): result = SparqlTranslator(query).translate() # Translated query should be unicode object. - assert isinstance(result, unicode) + assert isinstance(result, basestring) result = canonical(result) assert expected == result @@ -179,9 +181,9 @@ def test_str(): query = select("?s", "?p", "?o").where(("?s", "?p", "?o")) # test str() - assert expected == canonical(unicode(str(query))) + assert expected == canonical(str(str(query))) # test unicode() - assert expected == canonical(unicode(query)) + assert expected == canonical(str(query)) def test_ask(): diff --git a/surf/test/query/test_sparul.py b/surf/test/query/test_sparul.py index de825dd..8d30d3b 100644 --- a/surf/test/query/test_sparul.py +++ b/surf/test/query/test_sparul.py @@ -1,4 +1,6 @@ -import pytest +from builtins import str +from past.builtins import basestring, unicode + import re from surf.query.update import insert, load, delete, clear @@ -14,7 +16,7 @@ def canonical(sparql_string): capitalization differences. """ - assert(isinstance(sparql_string, unicode)) + assert(isinstance(sparql_string, basestring)) result = sparql_string.strip().lower() result = re.sub("\s\s+", " ", result) @@ -147,7 +149,7 @@ def test_unicode(): statement = URIRef("http://a"), URIRef("http://b"), URIRef("http://c") query = insert().template(statement) result = SparulTranslator(query).translate() - assert isinstance(result, unicode) + assert isinstance(result, basestring) def test_str(): @@ -160,6 +162,6 @@ def test_str(): query = insert().template(statement) # test str() - assert expected == canonical(unicode(str(query))) + assert expected == canonical(str(unicode(query))) # test unicode() - assert expected == canonical(unicode(query)) + assert expected == canonical(str(query)) diff --git a/surf/test/resource/test_resource.py b/surf/test/resource/test_resource.py index 6ff4395..6461b19 100644 --- a/surf/test/resource/test_resource.py +++ b/surf/test/resource/test_resource.py @@ -1,9 +1,14 @@ +from builtins import str +from builtins import range +from builtins import object +from past.builtins import basestring import pytest import surf from surf import Resource from surf.rdf import URIRef -from surf.util import uri_split +from surf.util import uri_split, error_message from rdflib.term import Literal +from surf.util import error_message @pytest.fixture @@ -135,7 +140,7 @@ def test_default_namespace(store_session): Person = session.get_class(surf.ns.FOAF.Person) surf.ns.register_fallback("http://example.com/ns#") p = Person() - assert unicode(p.subject).startswith("http://example.com/ns#") + assert str(p.subject).startswith("http://example.com/ns#") def test_multiple_sessions(store_session): @@ -166,8 +171,8 @@ def test_instance(store_session): subject = surf.ns.SURF.test1 Thing._instance(subject, [surf.ns.OWL.Thing], store=Thing.store_key) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) @pytest.mark.skip(reason="type mapping hasn't been implemented yet") @@ -187,7 +192,7 @@ def test_type_mapping(store_session): t1.save() t1 = Thing("http://t1") - assert type(t1.surf_string_value.first) == unicode + assert type(t1.surf_string_value.first) == str assert type(t1.surf_bool_value.first) == bool assert type(t1.surf_float_value.first) == float assert type(t1.surf_int_value.first) == int @@ -245,8 +250,8 @@ def test_query_attribute_unicode(store_session): def mock_get_by(self, **kwargs): """ Verify that all passed keywords are strings. """ - for keyword in kwargs.keys(): - assert isinstance(keyword, str), \ + for keyword in list(kwargs.keys()): + assert isinstance(keyword, basestring), \ "Passed non-string keyword: %s" % keyword _, session = store_session @@ -257,8 +262,8 @@ def mock_get_by(self, **kwargs): # Patch ResultProxy with mock get_by method original_get_by, RP.get_by = RP.get_by, mock_get_by resource.query_attribute(u"foaf_knows") - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) finally: # Regardless of results, revert our patch so other tests are not # affected. diff --git a/surf/test/resource/test_resource_value.py b/surf/test/resource/test_resource_value.py index 293c66d..968f812 100644 --- a/surf/test/resource/test_resource_value.py +++ b/surf/test/resource/test_resource_value.py @@ -1,8 +1,10 @@ +from builtins import object import pytest import surf from rdflib.term import Literal from surf.resource.lazy import LazyResourceLoader from surf.resource.result_proxy import ResultProxy +from surf.util import error_message class MockStore(object): @@ -93,8 +95,8 @@ def test_limit_offset(store_value): try: store.expect_args({"limit": 10, "offset": 5}) list(value.limit(10).offset(5)) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_full(store_value): @@ -105,8 +107,8 @@ def test_full(store_value): try: store.expect_args({'full': True, 'direct_only': True}) list(value.full(direct_only=True)) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_order_desc(store_value): @@ -117,8 +119,8 @@ def test_order_desc(store_value): try: store.expect_args({"order": "some_attr", "desc": True}) list(value.order("some_attr").desc()) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_get_by(store_value): @@ -130,8 +132,8 @@ def test_get_by(store_value): expected = [(surf.ns.FOAF["name"], Literal(u"Jane"), True)] store.expect_args({"get_by": expected}) list(value.get_by(foaf_name="Jane")) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_context(store_value): @@ -142,8 +144,8 @@ def test_context(store_value): try: store.expect_args({"context": "my_context"}) list(value.context("my_context")) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_filter(store_value): @@ -154,8 +156,8 @@ def test_filter(store_value): try: store.expect_args({"filter": [(surf.ns.FOAF["name"], Literal(u"f"), True)]}) list(value.filter(foaf_name="f")) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_get_by_resource(store_value): @@ -168,5 +170,5 @@ def test_get_by_resource(store_value): expected = [(surf.ns.FOAF["knows"], resource.subject, True)] store.expect_args({"get_by": expected}) list(value.get_by(foaf_knows=resource)) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) diff --git a/surf/test/resource/test_result_proxy.py b/surf/test/resource/test_result_proxy.py index ef501c2..5c559a4 100644 --- a/surf/test/resource/test_result_proxy.py +++ b/surf/test/resource/test_result_proxy.py @@ -1,8 +1,9 @@ +from builtins import object import pytest from rdflib.term import Literal import surf from surf.resource.result_proxy import ResultProxy - +from surf.util import error_message class MockStore(object): def __init__(self): @@ -55,8 +56,8 @@ def test_limit_offset(store_proxy): try: store.expect_args({"limit": 10, "offset": 5}) list(proxy.limit(10).offset(5)) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_full(store_proxy): @@ -67,8 +68,8 @@ def test_full(store_proxy): try: store.expect_args({'full': True, 'direct_only': True}) list(proxy.full(direct_only=True)) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_order_desc(store_proxy): @@ -79,8 +80,8 @@ def test_order_desc(store_proxy): try: store.expect_args({"order": "some_attr", "desc": True}) list(proxy.order("some_attr").desc()) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_get_by(store_proxy): @@ -92,8 +93,8 @@ def test_get_by(store_proxy): expected = [(surf.ns.FOAF["name"], Literal(u"Jane"), True)] store.expect_args({"get_by": expected}) list(proxy.get_by(foaf_name="Jane")) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_context(store_proxy): @@ -104,8 +105,8 @@ def test_context(store_proxy): try: store.expect_args({"context": "my_context"}) list(proxy.context("my_context")) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_filter(store_proxy): @@ -116,8 +117,8 @@ def test_filter(store_proxy): try: store.expect_args({"filter": [(surf.ns.FOAF["name"], Literal(u"f"), True)]}) list(proxy.filter(foaf_name="f")) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_get_by_resource(store_proxy): @@ -130,5 +131,5 @@ def test_get_by_resource(store_proxy): expected = [(surf.ns.FOAF["knows"], resource.subject, True)] store.expect_args({"get_by" : expected}) list(proxy.get_by(foaf_knows = resource)) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) diff --git a/surf/test/test_session.py b/surf/test/test_session.py index a5c67d5..2f34c1d 100644 --- a/surf/test/test_session.py +++ b/surf/test/test_session.py @@ -2,6 +2,7 @@ import pytest from surf import Session, Store +from surf.util import error_message def test_close_multiples_stores(): @@ -17,5 +18,5 @@ def test_close_multiples_stores(): # Should not fail. session.close() - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) diff --git a/surf/test/test_store.py b/surf/test/test_store.py index 3dbbb6c..ded37e0 100644 --- a/surf/test/test_store.py +++ b/surf/test/test_store.py @@ -6,6 +6,7 @@ from surf import Session, Store from surf.plugin.reader import RDFReader from surf.plugin.writer import RDFWriter +from surf.util import error_message def test_multiples(): @@ -27,8 +28,8 @@ def test_multiples(): store.save(rob, michael) store.update(rob, michael) store.remove(rob, michael) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_close_unicode_exception(): @@ -86,8 +87,8 @@ def close(self): logging.disable(logging.ERROR) store.close() logging.disable(logging.NOTSET) - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) def test_successful_close(): @@ -143,5 +144,5 @@ def close(self): reader = MockReader() store = Store(reader, MockWriter(reader), log_level=logging.NOTSET) store.close() - except Exception, e: - pytest.fail(e.message, pytrace=True) + except Exception as e: + pytest.fail(error_message(e), pytrace=True) diff --git a/surf/test/test_util.py b/surf/test/test_util.py index 3396932..bbd4e20 100644 --- a/surf/test/test_util.py +++ b/surf/test/test_util.py @@ -1,3 +1,4 @@ +from builtins import object import pytest import decimal diff --git a/surf/util.py b/surf/util.py index c6b3226..01a2cb5 100644 --- a/surf/util.py +++ b/surf/util.py @@ -1,3 +1,4 @@ +from builtins import str # Copyright (c) 2009, Digital Enterprise Research Institute (DERI), # NUI Galway # All rights reserved. @@ -33,12 +34,17 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # -*- coding: utf-8 -*- +from future import standard_library +standard_library.install_aliases() +from past.builtins import basestring +from builtins import object import logging from datetime import datetime, date, time import decimal import re -from urlparse import urlparse +from urllib.parse import urlparse from uuid import uuid4 +import sys from surf.namespace import get_namespace, get_namespace_url from surf.namespace import get_fallback_namespace, SURF @@ -62,6 +68,23 @@ pattern = re.compile('([A-Z][A-Z][a-z])|([a-z][A-Z])') +def error_message(exception): + """ Returns the message passed to the exception + (For compatibility reason.) Since Py2.6, Exception("something").message was deprecated. + It is not available in python 3. To simplify access to the message, we use this function. + + :param exception: An Exception + :type exception: BaseException + :return: Exception message + :rtype: str + """ + if sys.version_info[0] < 3: + return exception.message + elif len(exception.args): + return exception.args[0] + raise Exception("Error message was not possible to retrieve due to version compatibility") + + # ---------------------------------------------------------------------------------------------------------------------- # # module functions @@ -89,7 +112,7 @@ def namespace_split(uri): (rdflib.URIRef('http://mynamespace/ns#'), 'some_property') :param str uri: the uri - :return: a (namespace, predicate) tuple. Types: (:class:`rdflib.term.URIRef`, str) + :return: a (namespace, predicate) tuple. Types: (:class:`rdflib.term.URIRef`, basestring) :rtype: tuple """ @@ -110,7 +133,7 @@ def uri_split(uri): :param uri: the uri :type uri: :class:`rdflib.term.URIRef` or basestring - :return: a (base, remainder) tuple. Types: (str, str) + :return: a (base, remainder) tuple. Types: (str, basestring) :rtype: tuple """ @@ -310,7 +333,7 @@ def pretty_rdf(uri): uri = uri.subject if type(uri) is URIRef: NS, symbol = uri_split(uri) - if unicode(NS).startswith('NS'): + if str(NS).startswith('NS'): pretty = symbol else: pretty = NS.lower() + ':' + symbol @@ -328,7 +351,7 @@ def value_to_rdf(value): """ if isinstance(value, (URIRef, BNode)): return value - elif isinstance(value, (basestring, str, unicode, float, int, long, bool, datetime, date, time, decimal.Decimal)): + elif isinstance(value, (basestring, str, float, int, bool, datetime, date, time, decimal.Decimal)): if type(value) is basestring and string_conforms_to_base64(value): return Literal(value, datatype=URIRef('http://www.w3.org/2001/XMLSchema#base64Binary')) return Literal(value)