Source code for tecplot.tecutil.util

from builtins import super

import inspect
import logging
import sys

from collections import Iterable, namedtuple
from contextlib import contextmanager
from ctypes import cast, c_int, POINTER
from six import string_types

from .tecinterprocess import _tecutil
from ..constant import Color
from ..exception import TecplotAttributeError, TecplotTypeError

log = logging.getLogger(__name__)

maxint64 = 2**(64 - 1) - 1
minint64 = -maxint64 - 1
maxuint64 = 2**64 - 1


[docs]class Index(int): """Position identifier type. This type is used internally to represent a position in a list. It is used to indicate that a change between zero-based indexing and one-based indexing must occur at the TecUtil boundary. This type can be treated exactly like a Python native `int` and is only meaningful internally to the tecplot Python module. """
IndexRange = namedtuple('IndexRange', ['min', 'max', 'step']) """Index range specification along some axis. This is similar to Python's `slice` object except that ``max`` is included in the evaluated indexes. Here are some things to note: * All indices start with 0 and go to some maximum index ``m``. * Negative values represent the indexes starting with the maximum at -1 and continuing back to the beginning of the range. * A step of `None`, 0 and 1 are all equivalent and mean that no elements are skipped. * A negative step indicates a skip less than the maximum. """ IndexRange.__new__.__defaults__ = (None, None, None) def flatten_args(*args): flatargs = [] for a in args: if isinstance(a, Iterable) and not isinstance(a, string_types): flatargs += list(a) else: flatargs.append(a) return tuple(flatargs) def array_to_enums(array_pointer, array_size, enum_type): indexes = cast(array_pointer, POINTER(c_int)) return tuple(enum_type(indexes[i]) for i in range(array_size)) def inherited_property(cls): def _copy_property(prop): attr = getattr(cls, prop.__name__) return property(attr.fget, attr.fset, attr.fdel, prop.__doc__) return _copy_property def log_setattr(cls): def _setattr(self, name, value): if __debug__: if not name.startswith('_') and name not in dir(self): stacknames = [f[0].f_code.co_name for f in inspect.stack()[:3]] if '__init__' not in stacknames: msg = 'No attribute: {}.{}' classname = self.__class__.__name__ raise TecplotAttributeError(msg.format(classname, name)) return super(cls, self).__setattr__(name, value) cls.__setattr__ = _setattr return cls @contextmanager def lock(with_recording=True): """ ParentLockStart takes a boolean: ShutdownImplicitRecording ShutdownImplicitRecording = True -> No recording ShutdownImplicitRecording = False -> With Recording """ _tecutil.ParentLockStart(not with_recording) try: yield finally: _tecutil.handle.tecUtilParentLockFinish() if sys.version_info < (3, 3): """ This allows the contextmanager lock to be used as a decorator as well as a context. (This is already included in Py 3.3+) """ from functools import wraps _lock = lock class lock(object): def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs self._cm = _lock def __enter__(self, *args, **kwargs): self.cm = self._cm(*self.args, **self.kwargs) return self.cm.__enter__(*args, **kwargs) def __exit__(self, *args, **kwargs): return self.cm.__exit__(*args, **kwargs) def __call__(self, func): @wraps(func) def wrapper(*args, **kwargs): with self._cm(*self.args, **self.kwargs): return func(*args, **kwargs) return wrapper _VarInfo = namedtuple('VarInfo', ('types', 'values', 'names')) def check_arglist_argtypes(function_name, *args): for arg in args: vinfo = _VarInfo(*arg) for name, value in zip(vinfo.names, vinfo.values): if value is not None: if not isinstance(value, tuple(vinfo.types)): errfmt = '{}: Type of parameter {} must be one of: {}' types = ', '.join(t.__name__ for t in vinfo.types) errmsg = errfmt.format(function_name, name, types) raise TecplotTypeError(errmsg) def color_spec(color, plot=None): """ color_spec(Color.Blue, plot) -> Color.Blue color_spec(Color.MultiColor, plot) -> plot.contour(0) color_spec(Color.Blue) -> Color.Blue color_spec(plot.contour(0)) -> Color.MultiColor """ color_spec._indexes = { Color.MultiColor: Index(0), Color.MultiColor2: Index(1), Color.MultiColor3: Index(2), Color.MultiColor4: Index(3), Color.MultiColor5: Index(4), Color.MultiColor6: Index(5), Color.MultiColor7: Index(6), Color.MultiColor8: Index(7)} color_spec._multicolors = {v: k for k, v in color_spec._indexes.items()} try: if plot: return plot.contour(color_spec._indexes[Color(color)]) else: return color_spec._multicolors[Index(color.index)] except (AttributeError, KeyError): return Color(color)