def __new__(cls, argname, arg, *allowed_types, **kwargs): allowed = listify_args(allowed_types) my_caller = get_kwarg(kwargs, 'caller') or (caller() + '()') if len(allowed) == 1: return TypeError('Argument {0} to {1} must be {2} (got {3})'.format( argname, my_caller, classname(allowed[0]), type(arg).__name__ )) else: return TypeError("Argument {0} to {1} must be one of ({2}) (got {3})".format( argname, my_caller, ', '.join(classname(a) for a in allowed), type(arg).__name__ ))
def __new__(cls, *args, **kwargs): """ TODO Move this to class level documentation, since it doesn't show up in Sphinx Takes several different forms. Given a number of arguments (possibly nested lists), a Tensor is created as expected. *This is the only form in which arguments may be specified without keywords.* `Tensor` can also be initialized by giving a list of dimensions for the `shape` (aliased as `dimension`) keyword argument, with a possible default value keyword argument `default_val`. Unless otherwise specified via the `dtype` keyword argument, it is assumed that the input data should be cast as a `numpy.float64`. """ # Pop off any special args or kwargs and store their values for later has_indices = False ret_val = None indices = None units = pop_kwarg(kwargs, 'units') name = kwargs.pop('name', None) #--------------------------------------------------------------------------------# # pop off any kwargs that the subclass's __init__ takes... subclass_kwargs = {} for supercls in cls.__mro__: if supercls is Tensor: break if hasattr(supercls, '__tensor_init__') and callable(supercls.__tensor_init__): if hasattr(supercls.__tensor_init__, 'getargspec'): argspec = supercls.__tensor_init__.getargspec() else: argspec = inspect.getargspec(supercls.__tensor_init__) for arg in argspec.args[1:]: subclass_kwargs[arg] = kwargs.pop(arg, None) #--------------------------------------------------------------------------------# # Check for indices... indices_kwarg = kwargs.pop('indices', None) if indices_kwarg is None and len(args) == 1 and isinstance(args[0], basestring): args = list(args) indices_kwarg = args.pop(0) args = tuple(args) index_range_set = pop_multikwarg(kwargs, 'index_range_set', 'in_set', 'set') if indices_kwarg is not None: has_indices = True indices = EinsumTensor.split_indices(indices_kwarg) if index_range_set is None: index_range_set = IndexRange.global_index_range_set shape = [] for idx in indices: if idx not in index_range_set.known_ranges: raise IndexError("unknown index '" + idx + "'") shape.append(index_range_set.known_ranges[idx].size) shape = tuple(shape) if "shape" in kwargs: kwshape = kwargs.pop('shape') if shape != kwshape: raise TypeError("inconsistent shape: indices '{}' indicate a shape of {}, but" " the keyword 'shape' was given with the shape {}".format( ",".join(indices), shape, kwshape )) kwargs['shape'] = shape #--------------------------------------------------------------------------------# # Now create a numpy.ndarray object... def_val = pop_kwarg(kwargs, 'default_val', 'default_value', 'default') or 0.0 # Set the default data type to float, unless the user specifies dtype = get_kwarg(kwargs, 'dtype') or float if not callable(dtype) and grendel.show_warnings: warn("dtype given to {0} constructor is not Callable and thus cannot be used for casting." \ " It is better to use callable types for dtype if possible; e.g. numpy.float64 instead" \ "of numpy.dtype('float64')".format(classname(cls))) kwargs['dtype'] = dtype # Typecast the default value if callable(dtype): def_val = dtype(def_val) # See if we have a shape... shape = pop_kwarg(kwargs, 'shape', 'dimension') # See if we have data... # This allows us to support the form Tensor(1, 2, 3, 4) if len(args) == 1 and isinstance(args[0], np.ndarray): data = args[0] else: data = listify_args(*args) if 'data' in kwargs: if data: raise TypeError("`data` may be specified as a keyword argument or as " \ "the regular arguments to {0} constructor, but not both.".format(classname(cls))) else: data = pop_kwarg('data') if shape and not isinstance(data, np.ndarray): has_content = False if len(args) != 0: has_content = True if not has_content: if def_val == 0.0: try: ret_val = np.zeros(shape=shape, **kwargs) except: raise else: ret_val = (np.ones(shape=shape, **kwargs) * def_val) else: if grendel.sanity_checking_enabled: # Check data length tmp = np.array(data) needed_data_size = 1 for dim in shape: needed_data_size *= dim try: tmp.reshape((needed_data_size,)) except ValueError: raise ValueError("Data provided to {0} constructor is incompatible with the shape {1}".format(classname(cls), shape)) # Check data type ret_val = np.array(data, **kwargs).reshape(shape) else: # Just pass on the data and any surviving kwargs try: if isinstance(data, np.ndarray) and ( len(kwargs) == 0 or (len(kwargs) == 1 and 'dtype' in kwargs and kwargs['dtype'] == data.dtype) ): # Just do a view ret_val = data.view(cls) else: # Otherwise, we need to call the numpy "constructor" (actually a factory function) of ndarray ret_val = np.array(data, **kwargs) except: # debugging breakpoint hook raise if shape and ret_val.shape != shape: raise ValueError("Shape mismatch: data shape {0} does not match specified shape {1}".format( data.shape, shape )) #--------------------------------------------------------------------------------# # View-cast the ret_val to the class in question, but only if we haven't already if not isinstance(ret_val, cls): ret_val = ret_val.view(cls) # Now assign stuff from any special args... if has_indices: ret_val.indices = indices ret_val.index_range_set = index_range_set else: ret_val.indices = None ret_val.units = units ret_val.name = name if name is None: ret_val.name = "(unnamed tensor)" # pass the remaining kwargs to the initializer... ret_val.__tensor_init__(**subclass_kwargs) return ret_val
def __new__(cls, *args, **kwargs): """ TODO Move this to class level documentation, since it doesn't show up in Sphinx Takes several different forms. Given a number of arguments (possibly nested lists), a Tensor is created as expected. *This is the only form in which arguments may be specified without keywords.* `Tensor` can also be initialized by giving a list of dimensions for the `shape` (aliased as `dimension`) keyword argument, with a possible default value keyword argument `default_val`. Unless otherwise specified via the `dtype` keyword argument, it is assumed that the input data should be cast as a `numpy.float64`. """ # Pop off any special args or kwargs and store their values for later has_indices = False ret_val = None indices = None units = pop_kwarg(kwargs, 'units') name = kwargs.pop('name', None) #--------------------------------------------------------------------------------# # pop off any kwargs that the subclass's __init__ takes... subclass_kwargs = {} for supercls in cls.__mro__: if supercls is Tensor: break if hasattr(supercls, '__tensor_init__') and callable( supercls.__tensor_init__): if hasattr(supercls.__tensor_init__, 'getargspec'): argspec = supercls.__tensor_init__.getargspec() else: argspec = inspect.getargspec(supercls.__tensor_init__) for arg in argspec.args[1:]: subclass_kwargs[arg] = kwargs.pop(arg, None) #--------------------------------------------------------------------------------# # Check for indices... indices_kwarg = kwargs.pop('indices', None) if indices_kwarg is None and len(args) == 1 and isinstance( args[0], basestring): args = list(args) indices_kwarg = args.pop(0) args = tuple(args) index_range_set = pop_multikwarg(kwargs, 'index_range_set', 'in_set', 'set') if indices_kwarg is not None: has_indices = True indices = EinsumTensor.split_indices(indices_kwarg) if index_range_set is None: index_range_set = IndexRange.global_index_range_set shape = [] for idx in indices: if idx not in index_range_set.known_ranges: raise IndexError("unknown index '" + idx + "'") shape.append(index_range_set.known_ranges[idx].size) shape = tuple(shape) if "shape" in kwargs: kwshape = kwargs.pop('shape') if shape != kwshape: raise TypeError( "inconsistent shape: indices '{}' indicate a shape of {}, but" " the keyword 'shape' was given with the shape {}". format(",".join(indices), shape, kwshape)) kwargs['shape'] = shape #--------------------------------------------------------------------------------# # Now create a numpy.ndarray object... def_val = pop_kwarg(kwargs, 'default_val', 'default_value', 'default') or 0.0 # Set the default data type to float, unless the user specifies dtype = get_kwarg(kwargs, 'dtype') or float if not callable(dtype) and grendel.show_warnings: warn("dtype given to {0} constructor is not Callable and thus cannot be used for casting." \ " It is better to use callable types for dtype if possible; e.g. numpy.float64 instead" \ "of numpy.dtype('float64')".format(classname(cls))) kwargs['dtype'] = dtype # Typecast the default value if callable(dtype): def_val = dtype(def_val) # See if we have a shape... shape = pop_kwarg(kwargs, 'shape', 'dimension') # See if we have data... # This allows us to support the form Tensor(1, 2, 3, 4) if len(args) == 1 and isinstance(args[0], np.ndarray): data = args[0] else: data = listify_args(*args) if 'data' in kwargs: if data: raise TypeError("`data` may be specified as a keyword argument or as " \ "the regular arguments to {0} constructor, but not both.".format(classname(cls))) else: data = pop_kwarg('data') if shape and not isinstance(data, np.ndarray): has_content = False if len(args) != 0: has_content = True if not has_content: if def_val == 0.0: try: ret_val = np.zeros(shape=shape, **kwargs) except: raise else: ret_val = (np.ones(shape=shape, **kwargs) * def_val) else: if grendel.sanity_checking_enabled: # Check data length tmp = np.array(data) needed_data_size = 1 for dim in shape: needed_data_size *= dim try: tmp.reshape((needed_data_size, )) except ValueError: raise ValueError( "Data provided to {0} constructor is incompatible with the shape {1}" .format(classname(cls), shape)) # Check data type ret_val = np.array(data, **kwargs).reshape(shape) else: # Just pass on the data and any surviving kwargs try: if isinstance(data, np.ndarray) and ( len(kwargs) == 0 or (len(kwargs) == 1 and 'dtype' in kwargs and kwargs['dtype'] == data.dtype)): # Just do a view ret_val = data.view(cls) else: # Otherwise, we need to call the numpy "constructor" (actually a factory function) of ndarray ret_val = np.array(data, **kwargs) except: # debugging breakpoint hook raise if shape and ret_val.shape != shape: raise ValueError( "Shape mismatch: data shape {0} does not match specified shape {1}" .format(data.shape, shape)) #--------------------------------------------------------------------------------# # View-cast the ret_val to the class in question, but only if we haven't already if not isinstance(ret_val, cls): ret_val = ret_val.view(cls) # Now assign stuff from any special args... if has_indices: ret_val.indices = indices ret_val.index_range_set = index_range_set else: ret_val.indices = None ret_val.units = units ret_val.name = name if name is None: ret_val.name = "(unnamed tensor)" # pass the remaining kwargs to the initializer... ret_val.__tensor_init__(**subclass_kwargs) return ret_val
import os import subprocess from grendel.util.descriptors import RaiseOnAccessDescriptor from grendel.util.overloading import get_kwarg from grendel.util import SystemInfo # OS check... currently only 'posix' is supported if not os.name == 'posix': raise OSError("Q-Chem interface is currently only available on posix-like systems. " " This system returns '" + os.name + "' for the Python expression 'os.name'") SystemInfo.qchem_executable = get_kwarg(os.environ, 'QCHEM_EXECUTABLE', 'QCHEM_EXE', 'QCHEM') if not SystemInfo.qchem_executable: try: # try to find Q-Chem using `which`, which should be always available on posix systems # the last part strips the newline from the output SystemInfo.qchem_executable = subprocess.check_output(["which", 'qchem'])[:-1] if not os.access(SystemInfo.qchem_executable, os.X_OK): SystemInfo.qchem_executable = RaiseOnAccessDescriptor(SystemError, 'Q-Chem executable at {0} is not an executable file. Check the contents of the ' 'QCHEM_EXECUTABLE environment variable (or, if it is not defined, check the ' 'QCHEM_EXE or QCHEM environment variables.)'.format(SystemInfo.qchem_executable)) except subprocess.CalledProcessError: SystemInfo.qchem_executable = RaiseOnAccessDescriptor(SystemError, 'Q-Chem executable not found. Try a different interface or set the QCHEM_EXECUTABLE ' 'environment variable to the location of the executable. (Equivalently, you can set' ' either of the QCHEM or QCHEM_EXE environment variables.') # Check that the Q-Chem executable is in fact executable:
import os import subprocess from grendel.util.descriptors import RaiseOnAccessDescriptor from grendel.util.overloading import get_kwarg from grendel.util import SystemInfo # OS check... currently only 'posix' is supported if not os.name == 'posix': raise OSError( "Q-Chem interface is currently only available on posix-like systems. " " This system returns '" + os.name + "' for the Python expression 'os.name'") SystemInfo.qchem_executable = get_kwarg(os.environ, 'QCHEM_EXECUTABLE', 'QCHEM_EXE', 'QCHEM') if not SystemInfo.qchem_executable: try: # try to find Q-Chem using `which`, which should be always available on posix systems # the last part strips the newline from the output SystemInfo.qchem_executable = subprocess.check_output( ["which", 'qchem'])[:-1] if not os.access(SystemInfo.qchem_executable, os.X_OK): SystemInfo.qchem_executable = RaiseOnAccessDescriptor( SystemError, 'Q-Chem executable at {0} is not an executable file. Check the contents of the ' 'QCHEM_EXECUTABLE environment variable (or, if it is not defined, check the ' 'QCHEM_EXE or QCHEM environment variables.)'.format( SystemInfo.qchem_executable)) except subprocess.CalledProcessError: SystemInfo.qchem_executable = RaiseOnAccessDescriptor(