diff --git a/cubes/auth.py b/cubes/auth.py index 9bcaf168..995259fb 100644 --- a/cubes/auth.py +++ b/cubes/auth.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- -from __future__ import absolute_import + import os.path from collections import defaultdict @@ -67,7 +67,7 @@ def __init__(self, roles, allowed_cubes, denied_cubes, cell_restrictions, self.hierarchy_limits = defaultdict(list) if hierarchy_limits: - for cube, limits in hierarchy_limits.items(): + for cube, limits in list(hierarchy_limits.items()): for limit in limits: if isinstance(limit, compat.string_type): limit = string_to_dimension_level(limit) @@ -109,13 +109,13 @@ def merge(self, other): self.allowed_cubes |= other.allowed_cubes self.denied_cubes |= other.denied_cubes - for cube, restrictions in other.cell_restrictions.items(): + for cube, restrictions in list(other.cell_restrictions.items()): if not cube in self.cell_restrictions: self.cell_restrictions[cube] = restrictions else: self.cell_restrictions[cube] += restrictions - for cube, limits in other.hierarchy_limits.items(): + for cube, limits in list(other.hierarchy_limits.items()): if not cube in self.hierarchy_limits: self.hierarchy_limits[cube] = limits else: @@ -257,11 +257,11 @@ def __init__(self, rights_file=None, roles_file=None, roles=None, raise ConfigurationError("Unknown allow/deny order: %s" % order) # Process the roles - for key, info in roles.items(): + for key, info in list(roles.items()): role = right_from_dict(info) self.roles[key] = role - deps = dict((name, role.roles) for name, role in self.roles.items()) + deps = dict((name, role.roles) for name, role in list(self.roles.items())) order = sorted_dependencies(deps) for name in order: @@ -271,7 +271,7 @@ def __init__(self, rights_file=None, roles_file=None, roles=None, role.merge(parent) # Process rights - for key, info in rights.items(): + for key, info in list(rights.items()): right = right_from_dict(info) self.rights[key] = right diff --git a/cubes/calendar.py b/cubes/calendar.py index 4c727c91..eb6a6257 100644 --- a/cubes/calendar.py +++ b/cubes/calendar.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- """Date and time utilities.""" -from __future__ import absolute_import + import re diff --git a/cubes/common.py b/cubes/common.py index 406526a2..9dc3384a 100644 --- a/cubes/common.py +++ b/cubes/common.py @@ -3,7 +3,7 @@ """Utility functions for computing combinations of dimensions and hierarchy levels""" -from __future__ import absolute_import + import re import os.path @@ -41,7 +41,7 @@ def set(self, key, value): def __repr__(self): items = [] - for key, value in self.items(): + for key, value in list(self.items()): item = '%s: %s' % (repr(key), repr(value)) items.append(item) @@ -120,7 +120,7 @@ def expand_dictionary(record, separator='.'): `separator`, create sub-dictionaries as necessary""" result = {} - for key, value in record.items(): + for key, value in list(record.items()): current = result path = key.split(separator) for part in path[:-1]: @@ -143,7 +143,7 @@ def localize_attributes(attribs, translations): keys as attribute names, values are dictionaries with localizable attribute metadata, such as ``label`` or ``description``.""" - for (name, atrans) in translations.items(): + for (name, atrans) in list(translations.items()): attrib = attribs[name] localize_common(attrib, atrans) @@ -234,7 +234,7 @@ def coalesce_options(options, types): out = {} - for key, value in options.items(): + for key, value in list(options.items()): if key in types: out[key] = coalesce_option_value(value, types[key], key) else: @@ -283,13 +283,13 @@ def sorted_dependencies(graph): Will be: ``{"A": ["B"], "B": ["C", "D"], "D": ["E"],"E": []}`` """ - graph = dict((key, set(value)) for key, value in graph.items()) + graph = dict((key, set(value)) for key, value in list(graph.items())) # L ← Empty list that will contain the sorted elements L = [] # S ← Set of all nodes with no dependencies (incoming edges) - S = set(parent for parent, req in graph.items() if not req) + S = set(parent for parent, req in list(graph.items()) if not req) while S: # remove a node n from S @@ -299,7 +299,7 @@ def sorted_dependencies(graph): # for each node m with an edge e from n to m do # (n that depends on m) - parents = [parent for parent, req in graph.items() if n in req] + parents = [parent for parent, req in list(graph.items()) if n in req] for parent in parents: graph[parent].remove(n) @@ -309,7 +309,7 @@ def sorted_dependencies(graph): S.add(parent) # if graph has edges then -> error - nonempty = [k for k, v in graph.items() if v] + nonempty = [k for k, v in list(graph.items()) if v] if nonempty: raise ArgumentError("Cyclic dependency of: %s" diff --git a/cubes/compat.py b/cubes/compat.py index 6aa27b27..f3a6039d 100644 --- a/cubes/compat.py +++ b/cubes/compat.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- """Pytho compatibility utilities""" -from __future__ import absolute_import + import sys @@ -34,31 +34,31 @@ def open_unicode(filename): return open(filename, encoding="utf-8") else: - string_type = basestring + string_type = str binary_type = str - text_type = unicode - int_types = int, long + text_type = str + int_types = int, int - from urlparse import urlparse - from urllib2 import urlopen, build_opener - from urllib2 import HTTPPasswordMgrWithDefaultRealm - from urllib2 import HTTPBasicAuthHandler - from urllib import urlencode - from ConfigParser import SafeConfigParser as ConfigParser - from StringIO import StringIO - from Queue import Queue + from urllib.parse import urlparse + from urllib.request import urlopen, build_opener + from urllib.request import HTTPPasswordMgrWithDefaultRealm + from urllib.request import HTTPBasicAuthHandler + from urllib.parse import urlencode + from configparser import SafeConfigParser as ConfigParser + from io import StringIO + from queue import Queue reduce = reduce def to_str(b): return b def to_unicode(s): - if isinstance(s, unicode): + if isinstance(s, str): return s s = str(s) for enc in ('utf8', 'latin-1'): try: - return unicode(s, enc) + return str(s, enc) except UnicodeDecodeError: pass diff --git a/cubes/ext.py b/cubes/ext.py index fb0b13cf..214dc00c 100644 --- a/cubes/ext.py +++ b/cubes/ext.py @@ -202,7 +202,7 @@ def names(self): self.discover() names = list(self.builtins.keys()) - names += self.extensions.keys() + names += list(self.extensions.keys()) return sorted(names) diff --git a/cubes/formatters.py b/cubes/formatters.py index 01d9707f..781411a1 100644 --- a/cubes/formatters.py +++ b/cubes/formatters.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import print_function + import codecs import csv @@ -145,7 +145,7 @@ def __init__(self, iterable, separator='\n'): def __iter__(self): for obj in self.iterable: string = self.encoder.encode(obj) - yield u"{}{}".format(string, self.separator) + yield "{}{}".format(string, self.separator) class SlicerJSONEncoder(json.JSONEncoder): diff --git a/cubes/logging.py b/cubes/logging.py index c10e3d10..f8bcf8a1 100644 --- a/cubes/logging.py +++ b/cubes/logging.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import + from logging import getLogger, Formatter, StreamHandler, FileHandler diff --git a/cubes/mapper.py b/cubes/mapper.py index 927e05d6..854598ca 100644 --- a/cubes/mapper.py +++ b/cubes/mapper.py @@ -66,7 +66,7 @@ def all_attributes(self, expand_locales=False): """Return a list of all attributes of a cube. If `expand_locales` is ``True``, then localized logical reference is returned for each attribute's locale.""" - return self.attributes.values() + return list(self.attributes.values()) # TODO: depreciate in favor of Cube.attribute def attribute(self, name): diff --git a/cubes/metadata/__init__.py b/cubes/metadata/__init__.py index b78668cb..a4bba19e 100644 --- a/cubes/metadata/__init__.py +++ b/cubes/metadata/__init__.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- -from __future__ import absolute_import + from .base import * from .attributes import * diff --git a/cubes/metadata/attributes.py b/cubes/metadata/attributes.py index 2dbf367c..13c32d98 100644 --- a/cubes/metadata/attributes.py +++ b/cubes/metadata/attributes.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- -from __future__ import absolute_import + import copy @@ -380,11 +380,11 @@ def default_aggregates(self): for agg in self.aggregates or ["sum"]: if agg == "identity": - name = u"%s" % self.name + name = "%s" % self.name measure = None function = None else: - name = u"%s_%s" % (self.name, agg) + name = "%s_%s" % (self.name, agg) measure = self.name function = agg @@ -588,7 +588,7 @@ def depsort_attributes(attributes, all_dependencies): base = bases.pop() sorted_deps.append(base) - dependants = [attr for attr, deps in remaining.items() + dependants = [attr for attr, deps in list(remaining.items()) if base in deps] for attr in dependants: diff --git a/cubes/metadata/base.py b/cubes/metadata/base.py index 5e31656c..bcfeae9a 100644 --- a/cubes/metadata/base.py +++ b/cubes/metadata/base.py @@ -2,7 +2,7 @@ # -*- encoding: utf-8 -*- """Cube logical model""" -from __future__ import absolute_import + import json import os diff --git a/cubes/metadata/cube.py b/cubes/metadata/cube.py index 3517a660..aef68632 100644 --- a/cubes/metadata/cube.py +++ b/cubes/metadata/cube.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- """Cube logical model""" -from __future__ import absolute_import + from collections import OrderedDict, defaultdict @@ -31,12 +31,12 @@ # TODO: make this configurable IMPLICIT_AGGREGATE_LABELS = { - "sum": u"Sum of {measure}", - "count": u"Record Count", - "count_nonempty": u"Non-empty count of {measure}", - "min": u"{measure} Minimum", - "max": u"{measure} Maximum", - "avg": u"Average of {measure}", + "sum": "Sum of {measure}", + "count": "Record Count", + "count_nonempty": "Non-empty count of {measure}", + "min": "{measure} Minimum", + "max": "{measure} Maximum", + "avg": "Average of {measure}", } @@ -584,7 +584,7 @@ def distilled_hierarchies(self): for dim in self.dimensions: for hier in dim.hierarchies: key = (dim.name, hier.name) - levels = [hier_key.ref for hier_key in hier.keys()] + levels = [hier_key.ref for hier_key in list(hier.keys())] hierarchies[key] = levels @@ -806,7 +806,7 @@ def expand_cube_metadata(metadata): if dim_hiers: raise ModelError("There are hierarchies specified for non-linked " - "dimensions: %s." % (dim_hiers.keys())) + "dimensions: %s." % (list(dim_hiers.keys()))) nonadditive = metadata.pop("nonadditive", None) if "measures" in metadata: diff --git a/cubes/metadata/defaults.py b/cubes/metadata/defaults.py index efea612e..3c08571a 100644 --- a/cubes/metadata/defaults.py +++ b/cubes/metadata/defaults.py @@ -2,7 +2,7 @@ """Metadata validation """ -from __future__ import absolute_import + import pkgutil import json diff --git a/cubes/metadata/dimension.py b/cubes/metadata/dimension.py index c52ff3c1..54fa3806 100644 --- a/cubes/metadata/dimension.py +++ b/cubes/metadata/dimension.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- -from __future__ import absolute_import + import copy import re @@ -84,7 +84,7 @@ def from_metadata(cls, metadata, templates=None): hierarchies = [] level_dict = dict((level.name, level) for level in levels) - for hier in template._hierarchies.values(): + for hier in list(template._hierarchies.values()): hier_levels = [level_dict[level.name] for level in hier.levels] hier_copy = Hierarchy(hier.name, hier_levels, @@ -298,7 +298,7 @@ def __init__(self, name, levels=None, hierarchies=None, default_roles = _DEFAULT_LEVEL_ROLES.get(self.role) # Set default roles - for level in self._levels.values(): + for level in list(self._levels.values()): if default_roles and level.name in default_roles: level.role = level.name @@ -369,7 +369,7 @@ def has_details(self): if self.master: return self.master.has_details - return any([level.has_details for level in self._levels.values()]) + return any([level.has_details for level in list(self._levels.values())]) @property def levels(self): @@ -460,7 +460,7 @@ def key_attributes(self): """Return all dimension key attributes, regardless of hierarchy. Order is not guaranteed, use a hierarchy to have known order.""" - return [level.key for level in self._levels.values()] + return [level.key for level in list(self._levels.values())] @property def attributes(self): @@ -496,11 +496,11 @@ def clone(self, hierarchies=None, exclude_hierarchies=None, linked.append(self.hierarchy(name)) elif exclude_hierarchies: linked = [] - for hierarchy in self._hierarchies.values(): + for hierarchy in list(self._hierarchies.values()): if hierarchy.name not in exclude_hierarchies: linked.append(hierarchy) else: - linked = self._hierarchies.values() + linked = list(self._hierarchies.values()) hierarchies = [copy.deepcopy(hier) for hier in linked] @@ -576,7 +576,7 @@ def to_dict(self, **options): # Collect hierarchies and apply hierarchy depth restrictions hierarchies = [] hierarchy_limits = hierarchy_limits or {} - for name, hierarchy in self._hierarchies.items(): + for name, hierarchy in list(self._hierarchies.items()): if name in hierarchy_limits: level = hierarchy_limits[name] if level: @@ -640,7 +640,7 @@ def validate(self): attributes = set() first_occurence = {} - for level_name, level in self._levels.items(): + for level_name, level in list(self._levels.items()): if not level.attributes: results.append(('error', "Level '%s' in dimension '%s' has no " @@ -710,7 +710,7 @@ def localizable_dictionary(self): hdict = {} locale["hierarchies"] = hdict - for hier in self._hierarchies.values(): + for hier in list(self._hierarchies.values()): hdict[hier.name] = hier.localizable_dictionary() return locale @@ -784,7 +784,7 @@ def __deepcopy__(self, memo): label=self.label, description=self.description, info=copy.deepcopy(self.info, memo), - levels=copy.deepcopy(self._levels, memo).values()) + levels=copy.deepcopy(list(self._levels.values()), memo)) @property def levels(self): diff --git a/cubes/metadata/localization.py b/cubes/metadata/localization.py index 8c794c8f..5f527194 100644 --- a/cubes/metadata/localization.py +++ b/cubes/metadata/localization.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import + from .. import compat # Global Context – top level namespace and objects in other namespaces # Local Context - within object being translated diff --git a/cubes/metadata/model.py b/cubes/metadata/model.py index 11ec0766..6c83109d 100644 --- a/cubes/metadata/model.py +++ b/cubes/metadata/model.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- """Logical model.""" -from __future__ import absolute_import + import re import copy diff --git a/cubes/metadata/providers.py b/cubes/metadata/providers.py index fdf82e5c..4348158a 100644 --- a/cubes/metadata/providers.py +++ b/cubes/metadata/providers.py @@ -40,7 +40,7 @@ def link_cube(cube, locale, provider=None, namespace=None, linked = set() - for dim_name in cube.dimension_links.keys(): + for dim_name in list(cube.dimension_links.keys()): if dim_name in linked: raise ModelError("Dimension '{}' linked twice" .format(dim_name)) diff --git a/cubes/namespace.py b/cubes/namespace.py index 5edf76fe..d2ee3e76 100644 --- a/cubes/namespace.py +++ b/cubes/namespace.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import + from .errors import NoSuchCubeError, NoSuchDimensionError, ModelError from .common import read_json_file @@ -131,7 +131,7 @@ def list_cubes(self, recursive=False): all_cubes += cubes if recursive: - for name, ns in self.namespaces.items(): + for name, ns in list(self.namespaces.items()): cubes = ns.list_cubes(recursive=True) for cube in cubes: cube["name"] = "%s.%s" % (name, cube["name"]) diff --git a/cubes/query/browser.py b/cubes/query/browser.py index 938c9b81..06db0297 100644 --- a/cubes/query/browser.py +++ b/cubes/query/browser.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import + from collections import namedtuple @@ -465,7 +465,7 @@ def report(self, cell, queries): report_result = {} - for result_name, query in queries.items(): + for result_name, query in list(queries.items()): query_type = query.get("query") if not query_type: raise ArgumentError("No report query for '%s'" % result_name) @@ -1032,7 +1032,7 @@ def __len__(self): def __iter__(self): return self.drilldown.__iter__() - def __nonzero__(self): + def __bool__(self): return len(self.drilldown) > 0 DrilldownItem = namedtuple("DrilldownItem", @@ -1071,7 +1071,7 @@ def levels_from_drilldown(cell, drilldown): logger = get_logger() logger.warn("drilldown as dictionary is depreciated. Use a list of: " "(dim, hierarchy, level) instead") - drilldown = [(dim, None, level) for dim, level in drilldown.items()] + drilldown = [(dim, None, level) for dim, level in list(drilldown.items())] for obj in drilldown: if isinstance(obj, compat.string_type): diff --git a/cubes/query/cells.py b/cubes/query/cells.py index 8eb7b452..8b3c1528 100644 --- a/cubes/query/cells.py +++ b/cubes/query/cells.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import + import copy import re @@ -309,7 +309,7 @@ def rollup(self, rollup): new_cuts.append(cut) elif isinstance(self.drilldown, dict): - for (dim_name, level_name) in rollup.items(): + for (dim_name, level_name) in list(rollup.items()): cut = cuts[dim_name] if not cut: raise ArgumentError("No cut to roll-up for dimension '%s'" % dim_name) @@ -459,7 +459,7 @@ def __str__(self): def __repr__(self): return 'Cell(%s: %s)' % (str(self.cube), self.to_str() or 'All') - def __nonzero__(self): + def __bool__(self): """Returns `True` if the cell contains cuts.""" return bool(self.cuts) diff --git a/cubes/query/computation.py b/cubes/query/computation.py index d7e4730b..ea927718 100644 --- a/cubes/query/computation.py +++ b/cubes/query/computation.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- -from __future__ import absolute_import + import itertools diff --git a/cubes/query/statutils.py b/cubes/query/statutils.py index 74b0451e..b7e230aa 100644 --- a/cubes/query/statutils.py +++ b/cubes/query/statutils.py @@ -230,7 +230,7 @@ def __call__(self, record): def available_calculators(): """Returns a list of available calculators.""" - return CALCULATED_AGGREGATIONS.keys() + return list(CALCULATED_AGGREGATIONS.keys()) def aggregate_calculator_labels(): - return dict([(k, v.keywords['label']) for k, v in CALCULATED_AGGREGATIONS.items()]) + return dict([(k, v.keywords['label']) for k, v in list(CALCULATED_AGGREGATIONS.items())]) diff --git a/cubes/server/__init__.py b/cubes/server/__init__.py index 7e0f2ad5..9a0ac040 100644 --- a/cubes/server/__init__.py +++ b/cubes/server/__init__.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import + from .blueprint import slicer, API_VERSION from .base import run_server, create_server, read_slicer_config diff --git a/cubes/server/base.py b/cubes/server/base.py index 8265f224..b4cdcfc2 100644 --- a/cubes/server/base.py +++ b/cubes/server/base.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- -from __future__ import absolute_import + from .blueprint import slicer from flask import Flask import shlex diff --git a/cubes/server/browser.py b/cubes/server/browser.py index 789473e7..1aadc1ec 100644 --- a/cubes/server/browser.py +++ b/cubes/server/browser.py @@ -1,7 +1,7 @@ # -*- coding=utf -*- import json -import logging +from . import logging from ..logging import get_logger from ..query import * diff --git a/cubes/server/caching.py b/cubes/server/caching.py index c61d7598..f32e93f8 100644 --- a/cubes/server/caching.py +++ b/cubes/server/caching.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- import json -import logging +from . import logging from functools import update_wrapper, wraps from datetime import datetime, timedelta from exceptions import BaseException -import cPickle as pickle +import pickle as pickle import types from werkzeug.routing import Rule @@ -17,7 +17,7 @@ def _make_key_str(name, *args, **kwargs): if args: key_str += '::' + '::'.join([str(a) for a in args]) if kwargs: - key_str += '::' + '::'.join(['%s=%s' % (str(k), str(v)) for k, v in sorted(kwargs.items(), key=lambda x: x[0])]) + key_str += '::' + '::'.join(['%s=%s' % (str(k), str(v)) for k, v in sorted(list(kwargs.items()), key=lambda x: x[0])]) return key_str @@ -69,7 +69,7 @@ def _cache(self, *args, **kwargs): cache_impl = self.cache name = '%s.%s' % (self.__class__.__name__, fn.__name__) - key = _make_key_str(name, *args, **dict(additional_args.items() + kwargs.items())) + key = _make_key_str(name, *args, **dict(list(additional_args.items()) + list(kwargs.items()))) try: v = cache_impl.get(key) diff --git a/cubes/server/utils.py b/cubes/server/utils.py index fe189c48..e7a6633c 100644 --- a/cubes/server/utils.py +++ b/cubes/server/utils.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- -from __future__ import absolute_import + from flask import Request, Response, request, g diff --git a/cubes/slicer/commands.py b/cubes/slicer/commands.py index c186e506..746d50e5 100644 --- a/cubes/slicer/commands.py +++ b/cubes/slicer/commands.py @@ -7,8 +7,8 @@ environment variable. """ -from __future__ import absolute_import -from __future__ import print_function + + import json import os @@ -75,7 +75,7 @@ def extension_info(ctx, extension_type, extension_name): """Show info about Cubes extensions""" if extension_type == 'all': - types = ext.EXTENSION_TYPES.items() + types = list(ext.EXTENSION_TYPES.items()) else: label = ext.EXTENSION_TYPES[extension_type] types = [(extension_type, label)] @@ -94,7 +94,7 @@ def extension_info(ctx, extension_type, extension_name): if extension.options: click.echo("Configuration options:\n") - for option in extension.options.values(): + for option in list(extension.options.values()): name = option.get("name") desc = option.get("description", option.get("label")) desc = " - {}".format(desc) if desc else "" @@ -359,7 +359,7 @@ def denormalize(ctx, force, materialize, index, schema, cube, target): names = workspace.cube_names() targets = [store.naming.denormalized_table_name(name) for name in names] - cubes = zip(names, targets) + cubes = list(zip(names, targets)) for cube_name, target in cubes: cube = workspace.cube(cube_name) @@ -423,7 +423,7 @@ def sql_aggregate(ctx, force, index, schema, cube, target, dimensions): names = workspace.cube_names() targets = [store.naming.aggregated_table_name(name) for name in names] - cubes = zip(names, targets) + cubes = list(zip(names, targets)) for cube_name, target in cubes: cube = workspace.cube(cube_name) diff --git a/cubes/sql/__init__.py b/cubes/sql/__init__.py index 4f6dc6a4..843e8675 100644 --- a/cubes/sql/__init__.py +++ b/cubes/sql/__init__.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import + from .browser import * from .store import * diff --git a/cubes/sql/browser.py b/cubes/sql/browser.py index e563613e..4a5c70e6 100644 --- a/cubes/sql/browser.py +++ b/cubes/sql/browser.py @@ -1,7 +1,7 @@ # -*- encoding=utf -*- """SQL Browser""" -from __future__ import absolute_import + import collections @@ -223,7 +223,7 @@ def fact(self, key_value, fields=None): if row: # Convert SQLAlchemy object into a dictionary - record = dict(zip(labels, row)) + record = dict(list(zip(labels, row))) else: record = None @@ -336,7 +336,7 @@ def path_details(self, dimension, path, hierarchy=None): row = cursor.fetchone() if row: - member = dict(zip(labels, row)) + member = dict(list(zip(labels, row))) else: member = None @@ -407,7 +407,7 @@ def provide_aggregate(self, cell, aggregates, drilldown, split, order, if row: # Convert SQLAlchemy object into a dictionary - record = dict(zip(labels, row)) + record = dict(list(zip(labels, row))) else: record = None @@ -617,4 +617,4 @@ def __iter__(self): and any(row[agg] is None for agg in self.exclude_if_null): continue - yield dict(zip(self.labels, row)) + yield dict(list(zip(self.labels, row))) diff --git a/cubes/sql/expressions.py b/cubes/sql/expressions.py index 87985f33..4e681023 100644 --- a/cubes/sql/expressions.py +++ b/cubes/sql/expressions.py @@ -5,7 +5,7 @@ # generator is – is to remain as much Cubes-independent as possible, just be a # low level module somewhere between SQLAlchemy and Cubes. -from __future__ import absolute_import + import sqlalchemy.sql as sql diff --git a/cubes/sql/functions.py b/cubes/sql/functions.py index 5cf50038..697b1c28 100644 --- a/cubes/sql/functions.py +++ b/cubes/sql/functions.py @@ -198,5 +198,5 @@ def get_aggregate_function(name): def available_aggregate_functions(): """Returns a list of available aggregate function names.""" _create_function_dict() - return _function_dict.keys() + return list(_function_dict.keys()) diff --git a/cubes/sql/logging.py b/cubes/sql/logging.py index f79ba8db..060beb03 100644 --- a/cubes/sql/logging.py +++ b/cubes/sql/logging.py @@ -1,6 +1,6 @@ # -*- coding=utf -*- -from __future__ import absolute_import + from ...server.logging import RequestLogHandler, REQUEST_LOG_ITEMS from sqlalchemy import create_engine, Table, MetaData, Column diff --git a/cubes/sql/mapper.py b/cubes/sql/mapper.py index 0e553e80..ebc6c6d2 100644 --- a/cubes/sql/mapper.py +++ b/cubes/sql/mapper.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- """Logical to Physical Mappers""" -from __future__ import absolute_import + import re @@ -65,7 +65,7 @@ def distill_naming(dictionary): """Distill only keys and values related to the naming conventions.""" - d = {key: value for key, value in dictionary.items() + d = {key: value for key, value in list(dictionary.items()) if key in NAMING_DEFAULTS} return Naming(d) @@ -128,7 +128,7 @@ def __init__(self, *args, **kwargs): super(Naming, self).__init__(*args, **kwargs) # Set the defaults - for key, value in NAMING_DEFAULTS.items(): + for key, value in list(NAMING_DEFAULTS.items()): if key not in self: self[key] = value diff --git a/cubes/sql/query.py b/cubes/sql/query.py index 000339aa..3905d781 100644 --- a/cubes/sql/query.py +++ b/cubes/sql/query.py @@ -15,7 +15,7 @@ # similar attributes. No calls to Cubes object functions should be allowed # here. -from __future__ import absolute_import + import logging from collections import namedtuple @@ -652,7 +652,7 @@ def required_tables(self, attributes): sorted_tables = [fact] while required: - details = [table for table in required.values() + details = [table for table in list(required.values()) if table.join and self._master_key(table.join) in masters] @@ -667,7 +667,7 @@ def required_tables(self, attributes): if len(required) > 1: keys = [_format_key(table.key) - for table in required.values() + for table in list(required.values()) if table.key != fact_key] raise ModelError("Some tables are not joined: {}" diff --git a/cubes/sql/store.py b/cubes/sql/store.py index b48a8eff..7aca0dbe 100644 --- a/cubes/sql/store.py +++ b/cubes/sql/store.py @@ -1,6 +1,6 @@ # -*- encoding=utf -*- -from __future__ import absolute_import + try: import sqlalchemy as sa @@ -62,7 +62,7 @@ def sqlalchemy_options(options, prefix="sqlalchemy_"): and their types. The `options` are expected to have prefix ``sqlalchemy_``, which will be removed.""" - sa_keys = [key for key in options.keys() if key.startswith(prefix)] + sa_keys = [key for key in list(options.keys()) if key.startswith(prefix)] sa_options = {} for key in sa_keys: sa_key = key[11:] diff --git a/cubes/sql/utils.py b/cubes/sql/utils.py index 10030c00..aa7f7379 100644 --- a/cubes/sql/utils.py +++ b/cubes/sql/utils.py @@ -131,7 +131,7 @@ def order_query(statement, order, natural_order=None, labels=None): # Get logical attributes from column labels (see logical_labels # description for more information why this step is necessary) - columns = OrderedDict(zip(labels, statement.columns)) + columns = OrderedDict(list(zip(labels, statement.columns))) # Normalize order # --------------- @@ -153,11 +153,11 @@ def order_query(statement, order, natural_order=None, labels=None): # Collect natural order for selected columns that have no explicit # ordering - for (name, column) in columns.items(): + for (name, column) in list(columns.items()): if name in natural_order and name not in order_by: final_order[name] = order_column(column, natural_order[name]) - statement = statement.order_by(*final_order.values()) + statement = statement.order_by(*list(final_order.values())) return statement diff --git a/cubes/tutorial/sql.py b/cubes/tutorial/sql.py index 59552c80..0db3924a 100644 --- a/cubes/tutorial/sql.py +++ b/cubes/tutorial/sql.py @@ -87,5 +87,5 @@ def create_table_from_csv(connectable, file_name, table_name, fields, insert_command = table.insert() for row in reader: - record = dict(zip(field_names, row)) + record = dict(list(zip(field_names, row))) insert_command.execute(record) diff --git a/cubes/workspace.py b/cubes/workspace.py index b0163c1f..80cc2200 100644 --- a/cubes/workspace.py +++ b/cubes/workspace.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import + import os.path @@ -177,7 +177,7 @@ def __init__(self, config=None, stores=None, load_base_model=True, dict(store_config.items(store))) elif isinstance(stores, dict): - for name, store in stores.items(): + for name, store in list(stores.items()): self._register_store_dict(name, store) elif stores is not None: diff --git a/doc/conf.py b/doc/conf.py index f971448e..44e60855 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -43,8 +43,8 @@ master_doc = 'index' # General information about the project. -project = u'Cubes' -copyright = u'2010-2015, Stefan Urbanek' +project = 'Cubes' +copyright = '2010-2015, Stefan Urbanek' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -184,8 +184,8 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Cubes.tex', u'Cubes Documentation', - u'Stefan Urbanek', 'manual'), + ('index', 'Cubes.tex', 'Cubes Documentation', + 'Stefan Urbanek', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -217,6 +217,6 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'cubes', u'Cubes Documentation', - [u'Stefan Urbanek'], 1) + ('index', 'cubes', 'Cubes Documentation', + ['Stefan Urbanek'], 1) ] diff --git a/examples/hello_world/aggregate.py b/examples/hello_world/aggregate.py index 0515b0f5..fd11b0fb 100644 --- a/examples/hello_world/aggregate.py +++ b/examples/hello_world/aggregate.py @@ -1,4 +1,4 @@ -from __future__ import print_function + from cubes import Workspace, Cell, PointCut # 1. Create a workspace diff --git a/examples/hello_world/prepare_data.py b/examples/hello_world/prepare_data.py index 4737bd3f..0cc5487a 100644 --- a/examples/hello_world/prepare_data.py +++ b/examples/hello_world/prepare_data.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Data preparation for the hello_world example -from __future__ import print_function + from sqlalchemy import create_engine from cubes.tutorial.sql import create_table_from_csv diff --git a/examples/model_browser/application.py b/examples/model_browser/application.py index 1355255b..e707f18a 100644 --- a/examples/model_browser/application.py +++ b/examples/model_browser/application.py @@ -7,7 +7,7 @@ """ import argparse -import ConfigParser +import configparser from cubes import Workspace from flask import Flask, render_template @@ -64,7 +64,7 @@ def get_browser(): parser.add_argument('cube', nargs='?', default=None, help='cube name') args = parser.parse_args() - config = ConfigParser.SafeConfigParser() + config = configparser.SafeConfigParser() try: config.read(args.config) except Exception as e: diff --git a/setup.py b/setup.py index b96e8b60..4ec85f35 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="cubes", - version='1.1', + version='2.0', # Project uses reStructuredText, so ensure that the docutils get # installed or upgraded on the target machine diff --git a/tests/__init__.py b/tests/__init__.py index 744b2335..a956925a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,11 +1,11 @@ -from __future__ import absolute_import + import unittest import os from cubes.compat import py3k if not py3k: - unittest.TestCase.assertRaisesRegex = unittest.TestCase.assertRaisesRegexp + unittest.TestCase.assertRaisesRegex = unittest.TestCase.assertRaisesRegex from . import sql diff --git a/tests/sql/__init__.py b/tests/sql/__init__.py index 19921d8c..8a01bdc0 100644 --- a/tests/sql/__init__.py +++ b/tests/sql/__init__.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import + from .test_query import * from .test_browser import * diff --git a/tests/sql/common.py b/tests/sql/common.py index fa49c328..179d5bdf 100644 --- a/tests/sql/common.py +++ b/tests/sql/common.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- -from __future__ import absolute_import + import unittest import sqlalchemy as sa @@ -33,8 +33,8 @@ def create_table(engine, md, desc): if not types: types = ["string"] * len(desc["columns"]) - col_types = dict(zip(desc["columns"], desc["types"])) - for name, type_ in col_types.items(): + col_types = dict(list(zip(desc["columns"], desc["types"]))) + for name, type_ in list(col_types.items()): real_type = TYPES[type_] if type_ == 'id': col = sa.Column(name, real_type, primary_key=True) diff --git a/tests/sql/dw/demo.py b/tests/sql/dw/demo.py index 0d23315a..9483e9d6 100644 --- a/tests/sql/dw/demo.py +++ b/tests/sql/dw/demo.py @@ -18,7 +18,7 @@ # See: https://github.com/DataBrewery/cubes/issues/255 # -from __future__ import print_function + import sqlalchemy as sa import os diff --git a/tests/sql/test_browser.py b/tests/sql/test_browser.py index ebc5908c..ab23e292 100644 --- a/tests/sql/test_browser.py +++ b/tests/sql/test_browser.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -from __future__ import absolute_import + from unittest import TestCase, skip import sqlalchemy as sa diff --git a/tests/sql/test_expression.py b/tests/sql/test_expression.py index 03faa943..1d8e1c72 100644 --- a/tests/sql/test_expression.py +++ b/tests/sql/test_expression.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -from __future__ import absolute_import + import sqlalchemy as sa from sqlalchemy.sql.expression import ColumnElement diff --git a/tests/sql/test_query.py b/tests/sql/test_query.py index efb12021..3028460e 100644 --- a/tests/sql/test_query.py +++ b/tests/sql/test_query.py @@ -4,7 +4,7 @@ # objects into this test case # -from __future__ import absolute_import + import unittest import sqlalchemy as sa @@ -677,7 +677,7 @@ def setUp(self): } self.schema = StarSchema("star", self.md, mappings, self.fact) - self.base_attributes = create_list_of(Attribute, mappings.keys()) + self.base_attributes = create_list_of(Attribute, list(mappings.keys())) # self.base_attributes = list(mappings.keys()) self.base_deps = {attr:[] for attr in self.base_attributes} diff --git a/tests/test_expressions.py b/tests/test_expressions.py index dc9126fb..dbeee2f8 100644 --- a/tests/test_expressions.py +++ b/tests/test_expressions.py @@ -1,5 +1,5 @@ # -*- encoding=utf -*- -from __future__ import absolute_import + import unittest @@ -25,7 +25,7 @@ def setUp(self): self.attrs = {attr["name"]:Attribute.from_metadata(attr) for attr in attrs} self.deps = {name:attr.dependencies - for name, attr in self.attrs.items()} + for name, attr in list(self.attrs.items())} def attributes(self, *attrs): return [self.attrs[attr] for attr in attrs]