diff --git a/.travis.yml b/.travis.yml index 12580ef..f94e1aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,10 @@ language: python cache: pip sudo: required +python: + - "2.7" + - "3.6" + - "3.7-dev" # 3.7 development branch before_install: - sudo apt-get -qq update - sudo apt-get install -y gfortran diff --git a/carousel/__init__.py b/carousel/__init__.py index 8afd247..467554c 100644 --- a/carousel/__init__.py +++ b/carousel/__init__.py @@ -41,8 +41,8 @@ def get_current_version(*args, **kwargs): GIT_TAG = VERSION # if Git tag is none use version file VERSION = GIT_TAG # version -__author__ = u'Mark Mikofski' -__email__ = u'mark.mikofski@sunpowercorp.com' -__url__ = u'https://github.com/SunPower/Carousel' +__author__ = 'Mark Mikofski' +__email__ = 'mark.mikofski@sunpowercorp.com' +__url__ = 'https://github.com/SunPower/Carousel' __version__ = VERSION -__release__ = u'Caramel Corn' +__release__ = 'Caramel Corn' diff --git a/carousel/contrib/readers.py b/carousel/contrib/readers.py index 20c0f1d..2783b62 100644 --- a/carousel/contrib/readers.py +++ b/carousel/contrib/readers.py @@ -66,7 +66,7 @@ def load_data(self, *args, **kwargs): # get positional argument names from parameters and apply them to args # update data with additional kwargs argpos = { - v['extras']['argpos']: k for k, v in self.parameters.iteritems() + v['extras']['argpos']: k for k, v in self.parameters.items() if 'argpos' in v['extras'] } data = dict( @@ -85,7 +85,7 @@ def apply_units_to_cache(self, data): :return: data with units applied """ # if units key exists then apply - for k, v in self.parameters.iteritems(): + for k, v in self.parameters.items(): if v and v.get('units'): data[k] = Q_(data[k], v.get('units')) return data @@ -145,7 +145,7 @@ class HDF5Reader(ArgumentReader): def load_data(self, h5file, *args, **kwargs): with h5py.File(h5file) as h5f: h5data = dict.fromkeys(self.parameters) - for param, attrs in self.parameters.iteritems(): + for param, attrs in self.parameters.items(): LOGGER.debug('parameter:\n%r', param) node = attrs['extras']['node'] # full name of node # composite datatype member diff --git a/carousel/contrib/tests/test_data_readers.py b/carousel/contrib/tests/test_data_readers.py index 86f6dec..3a9e590 100644 --- a/carousel/contrib/tests/test_data_readers.py +++ b/carousel/contrib/tests/test_data_readers.py @@ -34,18 +34,18 @@ ('DirectNormalRadiation', ' 1: # more than one return, zip them up if idx is None: - out_reg.update(zip(returns, retval)) + out_reg.update(list(zip(returns, retval))) else: for k, v in zip(returns, retval): out_reg[k][idx] = v diff --git a/carousel/core/data_readers.py b/carousel/core/data_readers.py index 378fffb..0033a44 100644 --- a/carousel/core/data_readers.py +++ b/carousel/core/data_readers.py @@ -5,7 +5,7 @@ which are used to read in data sources. """ -from StringIO import StringIO +from io import StringIO from carousel.core import UREG, Q_ from carousel.core.exceptions import ( UnnamedDataError, MixedTextNoMatchError @@ -170,7 +170,7 @@ def apply_units_to_cache(self, data): :return: data with units applied :rtype: :class:`~pint.unit.Quantity` """ - for k, val in self.parameters.iteritems(): + for k, val in self.parameters.items(): if 'units' in val: data[k] = Q_(data[k], val.get('units')) return data @@ -254,7 +254,7 @@ def load_data(self, filename, *args, **kwargs): data = {} # an empty dictionary to store data # iterate through sheets in parameters # iterate through the parameters on each sheet - for param, pval in self.parameters.iteritems(): + for param, pval in self.parameters.items(): sheet = pval['extras']['sheet'] # get each worksheet from the workbook worksheet = workbook.sheet_by_name(sheet) @@ -280,7 +280,7 @@ def load_data(self, filename, *args, **kwargs): # if both elements are `list` then parameter is 2-D else: datum = [] - for col in xrange(prng0[1], prng1[1]): + for col in range(prng0[1], prng1[1]): datum.append(worksheet.col_values(col, prng0[0], prng1[0])) # duck typing that datum is real @@ -296,7 +296,7 @@ def load_data(self, filename, *args, **kwargs): # all([]) == True but any([]) == False if not datum: data[param] = None # convert empty to None - elif all(isinstance(_, basestring) for _ in datum): + elif all(isinstance(_, str) for _ in datum): data[param] = datum # all str is OK (EG all 'TMY') elif all(not _ for _ in datum): data[param] = None # convert list of empty to None @@ -319,7 +319,7 @@ def apply_units_to_cache(self, data): """ # iterate through sheets in parameters # iterate through the parameters on each sheet - for param, pval in self.parameters.iteritems(): + for param, pval in self.parameters.items(): # try to apply units try: data[param] *= UREG(str(pval.get('units') or '')) @@ -521,14 +521,14 @@ def _apply_units_to_numpy_data_readers(parameters, data): # dictionary of header field parameters header_fields = {field[0]: field[1:] for field in fields} # loop over fieldnames - for k, val in header_fields.iteritems(): + for k, val in header_fields.items(): # check for units in header field parameters if len(val) > 1: data[k] *= UREG(str(val[1])) # apply units # apply other data units data_units = parameters['data'].get('units') # default is None if data_units: - for k, val in data_units.iteritems(): + for k, val in data_units.items(): data[k] *= UREG(str(val)) # apply units return data @@ -577,16 +577,16 @@ def _read_header(f, header_param): header_reader = csv.DictReader(header_str, header_names, delimiter=header_delim, skipinitialspace=True) - data = header_reader.next() # parse the header dictionary + data = next(header_reader) # parse the header dictionary # iterate over items in data - for k, v in data.iteritems(): + for k, v in data.items(): header_type = header_fields[k][0] # spec'd type # whitelist header types - if isinstance(header_type, basestring): + if isinstance(header_type, str): if header_type.lower().startswith('int'): header_type = int # coerce to integer elif header_type.lower().startswith('long'): - header_type = long # coerce to long integer + header_type = int # coerce to long integer elif header_type.lower().startswith('float'): header_type = float # to floating decimal point elif header_type.lower().startswith('str'): @@ -666,7 +666,7 @@ def __init__(self, parameters): parameter_sheets = self.parameterization['parameter']['sheets'] for n, sheet in enumerate(parameter_sheets): new_parameters[sheet] = {} # empty dictionary for sheet data - for k, v in self.parameterization['data'].iteritems(): + for k, v in self.parameterization['data'].items(): new_parameters[sheet][k + '_' + str(n)] = v super(ParameterizedXLS, self).__init__(new_parameters) # filename is instance attribute of XLRDReader @@ -688,7 +688,7 @@ def load_data(self, filename, *args, **kwargs): for key in self.parameterization['data']: units = str(self.parameterization['data'][key].get('units')) or '' datalist = [] - for n in xrange(num_sheets): + for n in range(num_sheets): k = key + '_' + str(n) datalist.append(data[k].reshape((1, -1))) data.pop(k) # remove unused data keys @@ -778,9 +778,9 @@ def load_data(self, filename, *args, **kwargs): # load text data data = super(MixedTextXLS, self).load_data(filename) # iterate through sheets in parameters - for sheet_params in self.parameters.itervalues(): + for sheet_params in self.parameters.values(): # iterate through the parameters on each sheet - for param, pval in sheet_params.iteritems(): + for param, pval in sheet_params.items(): pattern = pval.get('pattern', EFG_PATTERN) # get pattern re_meth = pval.get('method', 'search') # get re method # whitelist re methods, getattr could be considered harmful diff --git a/carousel/core/data_sources.py b/carousel/core/data_sources.py index bdec134..e47f5cb 100644 --- a/carousel/core/data_sources.py +++ b/carousel/core/data_sources.py @@ -73,23 +73,23 @@ def register(self, newdata, *args, **kwargs): :raises: :exc:`~carousel.core.exceptions.UncertaintyPercentUnitsError` """ - kwargs.update(zip(self.meta_names, args)) + kwargs.update(list(zip(self.meta_names, args))) # check uncertainty has units of percent uncertainty = kwargs['uncertainty'] variance = kwargs['variance'] isconstant = kwargs['isconstant'] # check uncertainty is percent if uncertainty: - for k0, d in uncertainty.iteritems(): - for k1, v01 in d.iteritems(): + for k0, d in uncertainty.items(): + for k1, v01 in d.items(): units = v01.units if units != UREG('percent'): keys = '%s-%s' % (k0, k1) raise UncertaintyPercentUnitsError(keys, units) # check variance is square of uncertainty if variance and uncertainty: - for k0, d in variance.iteritems(): - for k1, v01 in d.iteritems(): + for k0, d in variance.items(): + for k1, v01 in d.items(): keys = '%s-%s' % (k0, k1) missing = k1 not in uncertainty[k0] v2 = np.asarray(uncertainty[k0][k1].to('fraction').m) ** 2.0 @@ -97,7 +97,7 @@ def register(self, newdata, *args, **kwargs): raise UncertaintyVarianceError(keys, v01) # check that isconstant is boolean if isconstant: - for k, v in isconstant.iteritems(): + for k, v in isconstant.items(): if not isinstance(v, bool): classname = self.__class__.__name__ error_msg = ['%s meta "isconstant" should be' % classname, @@ -126,7 +126,7 @@ def __new__(mcs, name, bases, attr): attr = mcs.set_meta(bases, attr) # set default meta attributes meta = attr[mcs._meta_attr] - for ma, dflt in mcs._attr_default.iteritems(): + for ma, dflt in mcs._attr_default.items(): a = getattr(meta, ma, None) if a is None: setattr(meta, ma, dflt) @@ -136,7 +136,7 @@ def __new__(mcs, name, bases, attr): return super(DataSourceBase, mcs).__new__(mcs, name, bases, attr) -class DataSource(object): +class DataSource(object, metaclass=DataSourceBase): """ Required interface for all Carousel data sources such as PVSim results, TMY3 data and calculation input files. @@ -154,7 +154,6 @@ class DataSource(object): This is the required interface for all source files containing data used in Carousel. """ - __metaclass__ = DataSourceBase def __init__(self, *args, **kwargs): # save arguments, might need them later @@ -217,8 +216,8 @@ def __init__(self, *args, **kwargs): self._raw_data = copy(self.data) # shallow copy of data self.__prepare_data__() # prepare data for registry # calculate variances - for k0, d in self.uncertainty.iteritems(): - for k1, v01 in d.iteritems(): + for k0, d in self.uncertainty.items(): + for k1, v01 in d.items(): self.variance[k0] = {k1: v01.to('fraction').m ** 2.0} def __prepare_data__(self): @@ -298,6 +297,6 @@ def __getitem__(self, item): def __repr__(self): parameters = getattr(self, DataSourceBase._param_attr) fmt = ('<%s(' % self.__class__.__name__) - fmt += ', '.join('%s=%r' % (k, v) for k, v in parameters.iteritems()) + fmt += ', '.join('%s=%r' % (k, v) for k, v in parameters.items()) fmt += ')>' return fmt diff --git a/carousel/core/formulas.py b/carousel/core/formulas.py index d9b5f0a..2244c1b 100644 --- a/carousel/core/formulas.py +++ b/carousel/core/formulas.py @@ -43,7 +43,7 @@ def register(self, new_formulas, *args, **kwargs): :param new_formulas: new formulas to add to registry. """ - kwargs.update(zip(self.meta_names, args)) + kwargs.update(list(zip(self.meta_names, args))) # call super method, meta must be passed as kwargs! super(FormulaRegistry, self).register(new_formulas, **kwargs) @@ -149,7 +149,7 @@ def import_formulas(self): # iterate through formulas for f in formula_param: formulas[f] = getattr(mod, f) - elif isinstance(formula_param, basestring): + elif isinstance(formula_param, str): # only one formula # FYI: use basestring to test for str and unicode # SEE: http://docs.python.org/2/library/functions.html#basestring @@ -172,7 +172,7 @@ class NumericalExpressionImporter(FormulaImporter): def import_formulas(self): formulas = {} # an empty list of formulas formula_param = self.parameters # formulas key - for f, p in formula_param.iteritems(): + for f, p in formula_param.items(): formulas[f] = lambda *args: ne.evaluate( p['extras']['expression'], {k: a for k, a in zip(p['args'], args)}, {} @@ -201,7 +201,7 @@ def __new__(mcs, name, bases, attr): return super(FormulaBase, mcs).__new__(mcs, name, bases, attr) -class Formula(object): +class Formula(object, metaclass=FormulaBase): """ A class for formulas. @@ -216,7 +216,6 @@ class Formula(object): This is the required interface for all source files containing formulas used in Carousel. """ - __metaclass__ = FormulaBase def __init__(self): # check for path listed in param file @@ -252,7 +251,7 @@ def __init__(self): # if formulas is a list or if it can't be iterated as a dictionary # then log warning and return try: - formula_param_generator = formula_param.iteritems() + formula_param_generator = iter(formula_param.items()) except AttributeError as err: LOGGER.warning('Attribute Error: %s', err.message) return @@ -285,7 +284,7 @@ def __init__(self): # check if retval units is a string or None before adding # extra units for Jacobian and covariance ret_units = self.units[k][0] - if isinstance(ret_units, basestring) or ret_units is None: + if isinstance(ret_units, str) or ret_units is None: self.units[k][0] = [ret_units] try: self.units[k][0] += [None, None] diff --git a/carousel/core/layers.py b/carousel/core/layers.py index cd83432..01b76c7 100644 --- a/carousel/core/layers.py +++ b/carousel/core/layers.py @@ -181,7 +181,7 @@ def load(self, rel_path=None): """ Add data_sources to layer and open files with data for the data_source. """ - for k, v in self.layer.iteritems(): + for k, v in self.layer.items(): self.add(k, v['module'], v.get('package')) filename = v.get('filename') path = v.get('path') @@ -193,7 +193,7 @@ def load(self, rel_path=None): path = os.path.join(rel_path, path) # filename can be a list or a string, concatenate list with # os.pathsep and append the full path to strings. - if isinstance(filename, basestring): + if isinstance(filename, str): filename = os.path.join(path, filename) else: file_list = [os.path.join(path, f) for f in filename] @@ -211,7 +211,7 @@ def edit(self, data_src, value): """ # check if opening file if 'filename' in value: - items = [k for k, v in self.reg.data_source.iteritems() if + items = [k for k, v in self.reg.data_source.items() if v == data_src] self.reg.unregister(items) # remove items from Registry # open file and register new data @@ -222,7 +222,7 @@ def delete(self, data_src): """ Delete data sources. """ - items = self.objects[data_src].data.keys() # items to edit + items = list(self.objects[data_src].data.keys()) # items to edit self.reg.unregister(items) # remove items from Registry self.layer.pop(data_src) # remove data source from layer self.objects.pop(data_src) # remove data_source object @@ -266,7 +266,7 @@ def load(self, _=None): """ Add formulas to layer. """ - for k, v in self.layer.iteritems(): + for k, v in self.layer.items(): self.add(k, v['module'], v.get('package')) def edit(self, src_cls, value): @@ -306,7 +306,7 @@ def load(self, _=None): """ Add calcs to layer. """ - for k, v in self.layer.iteritems(): + for k, v in self.layer.items(): self.add(k, v['module'], v.get('package')) def edit(self, src_cls, value): @@ -346,7 +346,7 @@ def load(self, _=None): """ Add output_source to layer. """ - for k, v in self.layer.iteritems(): + for k, v in self.layer.items(): self.add(k, v['module'], v.get('package')) def edit(self, src_cls, value): @@ -387,7 +387,7 @@ def load(self, rel_path=None): """ Add sim_src to layer. """ - for k, v in self.layer.iteritems(): + for k, v in self.layer.items(): self.add(k, v['module'], v.get('package')) filename = v.get('filename') path = v.get('path') diff --git a/carousel/core/models.py b/carousel/core/models.py index 1d1008f..362cfd3 100644 --- a/carousel/core/models.py +++ b/carousel/core/models.py @@ -67,21 +67,20 @@ def __new__(mcs, name, bases, attr): attr = mcs.set_param_file_or_parameters(attr) # set default meta attributes meta = attr[mcs._meta_attr] - for ma, dflt in mcs._attr_default.iteritems(): + for ma, dflt in mcs._attr_default.items(): a = getattr(meta, ma, None) if a is None: setattr(meta, ma, dflt) return super(ModelBase, mcs).__new__(mcs, name, bases, attr) -class Model(object): +class Model(object, metaclass=ModelBase): """ A class for models. Carousel is a subclass of the :class:`Model` class. :param modelfile: The name of the JSON file with model data. :type modelfile: str """ - __metaclass__ = ModelBase def __init__(self, modelfile=None): meta = getattr(self, ModelBase._meta_attr) @@ -133,7 +132,7 @@ def _load(self, layer=None): # read and load JSON parameter map file as "parameters" with open(self.param_file, 'r') as param_file: file_params = json.load(param_file) - for layer, params in file_params.iteritems(): + for layer, params in file_params.items(): # update parameters from file self.parameters[layer] = ModelParameter(**params) # if layer argument spec'd then only update/load spec'd layer @@ -176,7 +175,7 @@ def _initialize(self): # FIXME: move import inside loop for custom layers in different modules mod = importlib.import_module(meta.layers_mod, meta.layers_pkg) src_model = {} - for layer, value in self.model.iteritems(): + for layer, value in self.model.items(): # from layers module get the layer's class definition layer_cls = getattr(mod, meta.layer_cls_names[layer]) # class def self.layers[layer] = layer_cls # add layer class def to model @@ -189,7 +188,7 @@ def _initialize(self): except (TypeError, ValueError): kwargs = {} # no key work arguments # skip if not a source class - if isinstance(src, basestring): + if isinstance(src, str): continue # generate layer value from source class src_value[src.__name__] = {'module': src.__module__, @@ -205,7 +204,7 @@ def _initialize(self): value = dict(value['sources']) except ValueError: value = dict.fromkeys(value['sources'], {}) - for src in value.viewkeys(): + for src in value.keys(): if srcmod is not None: value[src]['module'] = srcmod if srcpkg is not None: @@ -252,7 +251,7 @@ def edit(self, layer, item, delete=False): if delete: return layer_obj # iterate over items and edit layer - for k, v in item.iteritems(): + for k, v in item.items(): if k in layer_obj.layer: layer_obj.edit(k, v) # edit layer else: @@ -267,14 +266,14 @@ def add(self, layer, items): """ Add items in model. """ - for k in items.iterkeys(): + for k in items.keys(): if k in self.model[layer]: raise Exception('item %s is already in layer %s' % (k, layer)) self.model[layer].update(items) # this should also update Layer.layer, the layer data # same as calling layer constructor # so now just need to add items to the layer - for k, v in items.iteritems(): + for k, v in items.items(): getattr(self, layer).add(k, v['module'], v.get('package')) def delete(self, layer, items): @@ -338,7 +337,7 @@ def command(self, cmd, progress_hook=None, *args, **kwargs): cmds = cmd.split(None, 1) # split commands and simulations sim_names = cmds[1:] # simulations if not sim_names: - sim_names = self.cmd_layer.reg.iterkeys() + sim_names = iter(self.cmd_layer.reg.keys()) for sim_name in sim_names: sim_cmd = getattr(self.cmd_layer.reg[sim_name], cmd) sim_cmd(self, progress_hook=progress_hook, *args, **kwargs) diff --git a/carousel/core/outputs.py b/carousel/core/outputs.py index 1288aa1..75cea54 100644 --- a/carousel/core/outputs.py +++ b/carousel/core/outputs.py @@ -47,7 +47,7 @@ def register(self, new_outputs, *args, **kwargs): :param new_outputs: new outputs to register. """ - kwargs.update(zip(self.meta_names, args)) + kwargs.update(list(zip(self.meta_names, args))) # call super method super(OutputRegistry, self).register(new_outputs, **kwargs) @@ -78,7 +78,7 @@ def __new__(mcs, name, bases, attr): return super(OutputBase, mcs).__new__(mcs, name, bases, attr) -class Output(object): +class Output(object, metaclass=OutputBase): """ A class for formatting outputs. @@ -103,7 +103,6 @@ class PVPowerOutputs(Output): hourly_energy = {'init': 0, 'units': 'Wh', 'size': 8760} yearly_energy = {'init': 0, 'units': 'kWh'} """ - __metaclass__ = OutputBase def __init__(self): #: outputs initial value @@ -126,7 +125,7 @@ def __init__(self): self.output_source = {} #: calculation outputs self.outputs = {} - for k, v in self.parameters.iteritems(): + for k, v in self.parameters.items(): self.initial_value[k] = v.get('init') # returns None if missing self.size[k] = v.get('size') or 1 # minimum size is 1 self.uncertainty[k] = None # uncertainty for outputs is calculated diff --git a/carousel/core/simulations.py b/carousel/core/simulations.py index 737e5d2..085c833 100644 --- a/carousel/core/simulations.py +++ b/carousel/core/simulations.py @@ -14,7 +14,7 @@ import os import sys import numpy as np -import Queue +import queue import functools from datetime import datetime @@ -47,11 +47,11 @@ def id_maker(obj): def sim_progress_hook(format_args, display_header=False): - if isinstance(format_args, basestring): + if isinstance(format_args, str): format_str = '---------- %s ----------\n' else: idx = format_args[0] - fields, values = zip(*format_args[1:]) + fields, values = list(zip(*format_args[1:])) format_str = '\r%5d' + ' %10.4g' * len(values) if display_header: units = (str(v.dimensionality) for v in values) @@ -79,19 +79,19 @@ def topological_sort(dag): `_ """ # find all edges of dag - topsort = [node for node, edge in dag.iteritems() if not edge] + topsort = [node for node, edge in dag.items() if not edge] # loop through nodes until topologically sorted while len(topsort) < len(dag): num_nodes = len(topsort) # number of nodes # unsorted nodes - for node in dag.viewkeys() - set(topsort): + for node in dag.keys() - set(topsort): # nodes with no incoming edges if set(dag[node]) <= set(topsort): topsort.append(node) break # circular dependencies if len(topsort) == num_nodes: - raise CircularDependencyError(dag.viewkeys() - set(topsort)) + raise CircularDependencyError(dag.keys() - set(topsort)) return topsort @@ -116,7 +116,7 @@ def register(self, sim, *args, **kwargs): :param sim: new simulation """ - kwargs.update(zip(self.meta_names, args)) + kwargs.update(list(zip(self.meta_names, args))) # call super method, now meta can be passed as args or kwargs. super(SimRegistry, self).register(sim, **kwargs) @@ -153,7 +153,7 @@ def __new__(mcs, name, bases, attr): return super(SimBase, mcs).__new__(mcs, name, bases, attr) -class Simulation(object): +class Simulation(object, metaclass=SimBase): """ A class for simulations. @@ -173,7 +173,6 @@ class attributes in a subclass or a combination of all 3 methods. Any additional settings provided as keyword arguments will override settings from file. """ - __metaclass__ = SimBase attrs = { 'ID': None, 'path': os.path.join('~', 'Carousel', 'Simulations'), @@ -201,7 +200,7 @@ def __init__(self, simfile=None, settings=None, **kwargs): file_params = json.load(param_file) #: simulation parameters from file self.parameters = {settings: SimParameter(**params) for - settings, params in file_params.iteritems()} + settings, params in file_params.items()} # if not subclassed and metaclass skipped, then use kwargs if not hasattr(self, 'parameters'): #: parameter file @@ -211,7 +210,7 @@ def __init__(self, simfile=None, settings=None, **kwargs): else: # use first settings if settings is None: - self.settings, self.parameters = self.parameters.items()[0] + self.settings, self.parameters = list(self.parameters.items())[0] else: #: name of sim settings used for parameters self.settings = settings @@ -225,13 +224,13 @@ def __init__(self, simfile=None, settings=None, **kwargs): self.write_frequency = 0 self.write_fields = {} # pop deprecated attribute names - for k, v in self.deprecated.iteritems(): + for k, v in self.deprecated.items(): val = self.parameters['extras'].pop(v, None) # update parameters if deprecated attr used and no new attr if val and k not in self.parameters: self.parameters[k] = val # Attributes - for k, v in self.attrs.iteritems(): + for k, v in self.attrs.items(): setattr(self, k, self.parameters.get(k, v)) # member docstrings are in documentation since attrs are generated if self.ID is None: @@ -242,12 +241,12 @@ def __init__(self, simfile=None, settings=None, **kwargs): self.path = os.path.expandvars(os.path.expanduser(self.path)) self.path = os.path.abspath(self.path) # convert simulation interval to Pint Quantity - if isinstance(self.interval, basestring): + if isinstance(self.interval, str): self.interval = UREG(self.interval) elif not isinstance(self.interval, Q_): self.interval = self.interval[0] * UREG(str(self.interval[1])) # convert simulation length to Pint Quantity - if isinstance(self.sim_length, basestring): + if isinstance(self.sim_length, str): self.sim_length = UREG(self.sim_length) elif not isinstance(self.sim_length, Q_): self.sim_length = self.sim_length[0] * UREG(str(self.sim_length[1])) @@ -266,7 +265,7 @@ def __init__(self, simfile=None, settings=None, **kwargs): #: order of calculations self.calc_order = [] #: command queue - self.cmd_queue = Queue.Queue() + self.cmd_queue = queue.Queue() #: index iterator self.idx_iter = self.index_iterator() #: data loaded status @@ -401,7 +400,7 @@ def start(self, model, progress_hook=None): _initial_value = out_reg.initial_value[k] if not _initial_value: continue - if isinstance(_initial_value, basestring): + if isinstance(_initial_value, str): # initial value is from data registry # assign in a scalar to a vector fills in the vector, yes! out_reg[k][-1] = data_reg[_initial_value] @@ -443,14 +442,14 @@ def start(self, model, progress_hook=None): self.interval_idx = idx_tot # update simulation interval counter idx = idx_tot % self.write_frequency # update properties - for k, v in out_reg.isproperty.iteritems(): + for k, v in out_reg.isproperty.items(): # set properties from previous interval at night if v: out_reg[k][idx] = out_reg[k][idx - 1] # night if any threshold exceeded if self.thresholds: night = not all(limits[0] < data_reg[data][idx] < limits[1] for - data, limits in self.thresholds.iteritems()) + data, limits in self.thresholds.items()) else: night = None # daytime or always calculated outputs @@ -495,7 +494,7 @@ def start(self, model, progress_hook=None): header=save_header, comments='') try: cmd = self.cmd_queue.get_nowait() - except Queue.Empty: + except queue.Empty: continue if cmd == 'pause': self._ispaused = True @@ -541,7 +540,7 @@ def load(self, model, progress_hook=None, *args, **kwargs): data = kwargs.get('data', {}) if not data and args: data = args[0] - for k, v in data.iteritems(): + for k, v in data.items(): progress_hook('loading simulation for %s' % k) model.data.open(k, **v) self.check_data(model.data) diff --git a/carousel/docs/conf.py b/carousel/docs/conf.py index 8dbdc4e..9723071 100644 --- a/carousel/docs/conf.py +++ b/carousel/docs/conf.py @@ -53,8 +53,8 @@ master_doc = 'index' # General information about the project. -project = u'Carousel' -copyright = u'2016, SunPower' +project = 'Carousel' +copyright = '2016, SunPower' author = __author__ # The version info for the project you're documenting, acts as replacement for @@ -245,7 +245,7 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, '%s.tex' % __name__, u'%s Documentation' % __name__, + (master_doc, '%s.tex' % __name__, '%s Documentation' % __name__, __author__, 'manual'), ] @@ -275,7 +275,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, __name__.lower(), u'%s Documentation' % __name__, + (master_doc, __name__.lower(), '%s Documentation' % __name__, [author], 1) ] @@ -289,7 +289,7 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, __name__, u'%s Documentation' % __name__, + (master_doc, __name__, '%s Documentation' % __name__, author, __name__, 'One line description of project.', 'Miscellaneous'), ] diff --git a/carousel/tests/test_calcs.py b/carousel/tests/test_calcs.py index f792625..b2f65a7 100644 --- a/carousel/tests/test_calcs.py +++ b/carousel/tests/test_calcs.py @@ -61,7 +61,7 @@ class CalcTest2(Calc): calc_test2 = CalcTest2() ok_(isinstance(calc_test2, Calc)) - for k, v in calc_test1.parameters.iteritems(): + for k, v in calc_test1.parameters.items(): eq_(calc_test2.parameters[k], v) @@ -92,7 +92,7 @@ def test_static_calc_unc(): lat_unc = uncertainties.ufloat(latitude, np.abs(latitude * lat_unc)) lon_unc = uncertainties.ufloat(longitude, np.abs(longitude * lon_unc)) test_unc = [] # empty list to collect return values - for n in xrange(96): + for n in range(96): # Uncertainties wrapped functions must return only scalar float f_ze_unc = uncertainties.wrap( lambda lat, lon: solpos(dt[n], lat, lon)['apparent_zenith'].item() diff --git a/carousel/tests/test_data.py b/carousel/tests/test_data.py index a1dba40..1ff3878 100644 --- a/carousel/tests/test_data.py +++ b/carousel/tests/test_data.py @@ -123,7 +123,7 @@ def __prepare_data__(self): data_test2 = DataSourceTest2(TUSCON) ok_(isinstance(data_test2, DataSource)) - for k, val in data_test1.parameters.iteritems(): + for k, val in data_test1.parameters.items(): eq_(data_test2.parameters[k], val) class DataSourceTest4(DataSource): diff --git a/carousel/tests/test_formulas.py b/carousel/tests/test_formulas.py index cfba426..988ade6 100644 --- a/carousel/tests/test_formulas.py +++ b/carousel/tests/test_formulas.py @@ -44,7 +44,7 @@ class Meta: formulas_test2 = FormulaTest2() ok_(isinstance(formulas_test2, Formula)) - for k, v in formulas_test2.parameters.iteritems(): + for k, v in formulas_test2.parameters.items(): eq_(formulas_test1.parameters[k], v) diff --git a/carousel/tests/test_outputs.py b/carousel/tests/test_outputs.py index f7792bd..53d63d0 100644 --- a/carousel/tests/test_outputs.py +++ b/carousel/tests/test_outputs.py @@ -36,5 +36,5 @@ class OutputTest2(Output): out_src_test2 = OutputTest2() ok_(isinstance(out_src_test2, Output)) - for k, v in out_src_test2.parameters.iteritems(): + for k, v in out_src_test2.parameters.items(): eq_(out_src_test1.parameters[k], v) diff --git a/carousel/tests/test_sim.py b/carousel/tests/test_sim.py index 76ca7b2..7ca6b6f 100644 --- a/carousel/tests/test_sim.py +++ b/carousel/tests/test_sim.py @@ -46,7 +46,7 @@ class Meta: data_reader = ArgumentReader def __prepare_data__(self): - keys = self.parameters.keys() + keys = list(self.parameters.keys()) for k in keys: if k.endswith('_unc'): unc = self.data.pop(k) diff --git a/examples/PVPower/formulas/utils.py b/examples/PVPower/formulas/utils.py index ce7088d..e9644b1 100644 --- a/examples/PVPower/formulas/utils.py +++ b/examples/PVPower/formulas/utils.py @@ -69,7 +69,7 @@ def groupby_freq(items, times, freq, wkst='SU'): :type wkst: str :return: generator """ - timeseries = zip(times, items) # timeseries map of items + timeseries = list(zip(times, items)) # timeseries map of items # create a key lambda to group timeseries by if freq.upper() == 'DAILY': def key(ts_): return ts_[0].day @@ -77,7 +77,7 @@ def key(ts_): return ts_[0].day weekday = getattr(rrule, wkst.upper()) # weekday start # generator that searches times for weekday start days = (day for day in times if day.weekday() == weekday.weekday) - day0 = days.next() # first weekday start of all times + day0 = next(days) # first weekday start of all times def key(ts_): return (ts_[0] - day0).days // 7 else: diff --git a/examples/PVPower/pvpower/sandia_perfmod_newstyle.py b/examples/PVPower/pvpower/sandia_perfmod_newstyle.py index 3d637ef..f840e31 100644 --- a/examples/PVPower/pvpower/sandia_perfmod_newstyle.py +++ b/examples/PVPower/pvpower/sandia_perfmod_newstyle.py @@ -45,7 +45,7 @@ def __prepare_data__(self): self.data[k] = k self.isconstant[k] = True # apply metadata - for k, v in parameters.iteritems(): + for k, v in parameters.items(): # TODO: this should be applied in data reader using _meta_names from # data registry which should use a meta class and all parameter # files should have same layout even xlrd and numpy readers, etc. diff --git a/examples/PVPower/pvpower/sandia_performance_model.py b/examples/PVPower/pvpower/sandia_performance_model.py index de5f2e7..3191745 100644 --- a/examples/PVPower/pvpower/sandia_performance_model.py +++ b/examples/PVPower/pvpower/sandia_performance_model.py @@ -38,7 +38,7 @@ def __prepare_data__(self): self.data[k] = k self.isconstant[k] = True # apply metadata - for k, v in parameters.iteritems(): + for k, v in parameters.items(): # TODO: this should be applied in data reader using _meta_names from # data registry which should use a meta class and all parameter # files should have same layout even xlrd and numpy readers, etc. diff --git a/examples/PVPower/pvpower/tests/test_pvpower.py b/examples/PVPower/pvpower/tests/test_pvpower.py index 0c7e79e..f15b49d 100644 --- a/examples/PVPower/pvpower/tests/test_pvpower.py +++ b/examples/PVPower/pvpower/tests/test_pvpower.py @@ -44,7 +44,7 @@ def test_daterange(): 'HOURLY', TZ, dtstart=DTSTART, count=test_range ) dtstart_local = PST.localize(DTSTART) - for hour in xrange(test_range): + for hour in range(test_range): assert dates[hour] == dtstart_local + timedelta(hours=hour) assert dates[hour].tzinfo.zone == TZ return dates