# # Copyright 2016 Pixar # # Licensed under the Apache License, Version 2.0 (the "Apache License") # with the following modification; you may not use this file except in # compliance with the Apache License and the following modification to it: # Section 6. Trademarks. is deleted and replaced with: # # 6. Trademarks. This License does not grant permission to use the trade # names, trademarks, service marks, or product names of the Licensor # and its affiliates, except as required to comply with Section 4(c) of # the License and to reproduce the content of the NOTICE file. # # You may obtain a copy of the Apache License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the Apache License with the above modification is # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the Apache License for the specific # language governing permissions and limitations under the Apache License. # """ Tf -- Tools Foundation """ def PrepareModule(module, result): """PrepareModule(module, result) -- Prepare an extension module at import time. Generally, this should only be called by the __init__.py script for a module upon loading a boost python module (generally '_LibName.so').""" # inject into result. ignore = frozenset(['__name__', '__builtins__', '__doc__', '__file__', '__path__']) newModuleName = result.get('__name__') for key, value in module.__dict__.items(): if not key in ignore: result[key] = value # Lie about the module from which value came. if newModuleName and hasattr(value, '__module__'): try: setattr(value, '__module__', newModuleName) except AttributeError as e: # The __module__ attribute of Boost.Python.function # objects is not writable, so we get this exception # a lot. Just ignore it. We're really only concerned # about the data objects like enum values and such. # pass def GetCodeLocation(framesUp): """Returns a tuple (moduleName, functionName, fileName, lineNo). To trace the current location of python execution, use GetCodeLocation(). By default, the information is returned at the current stack-frame; thus info = GetCodeLocation() will return information about the line that GetCodeLocation() was called from. One can write: def genericDebugFacility(): info = GetCodeLocation(1) # print out data def someCode(): ... if bad: genericDebugFacility() and genericDebugFacility() will get information associated with its caller, i.e. the function someCode().""" import sys f_back = sys._getframe(framesUp).f_back return (f_back.f_globals['__name__'], f_back.f_code.co_name, f_back.f_code.co_filename, f_back.f_lineno) # for some strange reason, this errors out when we try to reload it, # which is odd since _tf is a DSO and can't be reloaded anyway: import sys if "pxr.Tf._tf" not in sys.modules: from . import _tf PrepareModule(_tf, locals()) del _tf del sys # Need to provide an exception type that tf errors will show up as. class ErrorException(RuntimeError): def __init__(self, *args): RuntimeError.__init__(self, *args) self.__TfException = True def __str__(self): return '\n\t' + '\n\t'.join([str(e) for e in self.args]) __SetErrorExceptionClass(ErrorException) try: from . import __DOC __DOC.Execute(locals()) del __DOC except Exception: pass def Warn(msg, template=""): """Issue a warning via the TfDiagnostic system. At this time, template is ignored. """ codeInfo = GetCodeLocation(framesUp=1) _Warn(msg, codeInfo[0], codeInfo[1], codeInfo[2], codeInfo[3]) def Status(msg, verbose=True): """Issues a status update to the Tf diagnostic system. If verbose is True (the default) then information about where in the code the status update was issued from is included. """ if verbose: codeInfo = GetCodeLocation(framesUp=1) _Status(msg, codeInfo[0], codeInfo[1], codeInfo[2], codeInfo[3]) else: _Status(msg, "", "", "", 0) def RaiseCodingError(msg): """Raise a coding error to the Tf Diagnostic system.""" codeInfo = GetCodeLocation(framesUp=1) _RaiseCodingError(msg, codeInfo[0], codeInfo[1], codeInfo[2], codeInfo[3]) def RaiseRuntimeError(msg): """Raise a runtime error to the Tf Diagnostic system.""" codeInfo = GetCodeLocation(framesUp=1) _RaiseRuntimeError(msg, codeInfo[0], codeInfo[1], codeInfo[2], codeInfo[3]) def Fatal(msg): """Raise a fatal error to the Tf Diagnostic system.""" codeInfo = GetCodeLocation(framesUp=1) _Fatal(msg, codeInfo[0], codeInfo[1], codeInfo[2], codeInfo[3]) class NamedTemporaryFile(object): """A named temporary file which keeps the internal file handle closed. A class which constructs a temporary file(that isn't open) on __enter__, provides its name as an attribute, and deletes it on __exit__. Note: The constructor args for this object match those of python's tempfile.mkstemp() function, and will have the same effect on the underlying file created.""" def __init__(self, suffix='', prefix='', dir=None, text=False): # Note that we defer creation until the enter block to # prevent users from unintentionally creating a bunch of # temp files that don't get cleaned up. self._args = (suffix, prefix, dir, text) def __enter__(self): from tempfile import mkstemp from os import close fd, path = mkstemp(*self._args) close(fd) # XXX: We currently only expose the name attribute # more can be added based on client needs in the future. self._name = path return self def __exit__(self, *args): import os os.remove(self.name) @property def name(self): """The path for the temporary file created.""" return self._name