/usr/lib/python2.7/dist-packages/woo/__init__.py is in python-woo 1.0+dfsg1-1+b4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | # The purpose of this file is twofold:
# 1. it tells python that woo (this directory) is package of python modules
# see http://http://www.python.org/doc/2.1.3/tut/node8.html#SECTION008400000000000000000
#
# 2. import the runtime namespace (will be populated from within c++)
#
"""Common initialization core for woo.
This file is executed when anything is imported from woo for the first time.
It loads woo plugins and injects c++ class constructors to the __builtins__
(that might change in the future, though) namespace, making them available
everywhere.
"""
# FIXME: rename once tested
from wooMain import options as wooOptions
import warnings,traceback
import sys,os,os.path,re,string
WIN=sys.platform=='win32'
PY3K=(sys.version_info[0]==3)
if WIN:
class WooOsEnviron:
'''Class setting env vars via both CRT and win32 API, so that values can be read back
with getenv. This is needed for proper setup of OpenMP (which read OMP_NUM_THREADS).'''
def __setitem__(self,name,val):
import ctypes
# in windows set, value in CRT in addition to the one manipulated via win32 api
# http://msmvps.com/blogs/senthil/archive/2009/10/413/when-what-you-set-is-not-what-you-get-setenvironmentvariable-and-getenv.aspx
## use python's runtime
##ctypes.cdll[ctypes.util.find_msvcrt()]._putenv("%s=%s"%(name,value))
# call MSVCRT (unversioned) as well
ctypes.cdll.msvcrt._putenv("%s=%s"%(name,val))
os.environ[name]=val
def __getitem__(self,name): return os.environ[name]
wooOsEnviron=WooOsEnviron()
# this was set in wooMain (with -D, -vv etc), set again so that c++ sees it
if 'WOO_DEBUG' is os.environ: wooOsEnviron['WOO_DEBUG']=os.environ['WOO_DEBUG']
else:
wooOsEnviron=os.environ
# this is for GTS imports, must be set before compiled modules are imported
wooOsEnviron['LC_NUMERIC']='C'
# we cannot check for the 'openmp' feature yet, since woo.config is a compiled module
# we set the variable as normally, but will warn below, once the compiled module is imported
if wooOptions.ompCores:
cc=wooOptions.ompCores
if wooOptions.ompThreads!=len(cc) and wooOptions.ompThreads>0:
print 'wooOptions.ompThreads =',str(wooOptions.ompThreads)
warnings.warn('ompThreads==%d ignored, using %d since ompCores are specified.'%(wooOptions.ompThreads,len(cc)))
wooOptions.ompThreads=len(cc)
wooOsEnviron['GOMP_CPU_AFFINITY']=' '.join([str(cc[0])]+[str(c) for c in cc])
wooOsEnviron['OMP_NUM_THREADS']=str(len(cc))
elif wooOptions.ompThreads:
wooOsEnviron['OMP_NUM_THREADS']=str(wooOptions.ompThreads)
elif 'OMP_NUM_THREADS' not in os.environ:
import multiprocessing
wooOsEnviron['OMP_NUM_THREADS']=str(multiprocessing.cpu_count())
import distutils.sysconfig
soSuffix=distutils.sysconfig.get_config_vars()['SO']
#if WIN and 'TERM' in os.environ:
# # unbuffered output on windows, in case we're in a real terminal
# # http://stackoverflow.com/a/881751
# import msvcrt
# msvcrt.setmode(sys.stdout.fileno(),os.O_BINARY)
#
# QUIRKS
#
# not in Windows, and not when running without X (the check is not very reliable
if not WIN and (wooOptions.quirks & wooOptions.quirkIntel) and 'DISPLAY' in os.environ:
import os,subprocess
try:
vgas=subprocess.check_output("LC_ALL=C lspci | grep VGA",shell=True,stderr=subprocess.STDOUT,universal_newlines=True).split('\n')
if len(vgas)==1 and 'Intel' in vgas[0]:
# popen does not raise exception if it fails
try:
glx=subprocess.check_output("LC_ALL=C glxinfo | grep 'OpenGL version string:'",shell=True,stderr=subprocess.STDOUT,universal_newlines=True).split('\n')
# this should cover broken drivers down to Ubuntu 12.04 which shipped Mesa 8.0
if len(glx)==1 and re.match('.* Mesa (9\.[01]|8\.0)\..*',glx[0]):
print 'Intel GPU + Mesa < 9.2 detected, setting LIBGL_ALWAYS_SOFTWARE=1\n\t(use --quirks=0 to disable)'
os.environ['LIBGL_ALWAYS_SOFTWARE']='1'
except subprocess.CalledProcessError: pass # failed glxinfo call, such as when not installed
except subprocess.CalledProcessError: pass # failed lspci call...?!
if WIN:
# http://stackoverflow.com/questions/1447575/symlinks-on-windows/4388195#4388195
#
# unfortunately symlinks are something dangerous under windows, it is a priviledge which must be granted
# BUT the user must NOT be in the Administrators group?!
# http://superuser.com/questions/124679/how-do-i-create-an-mklink-in-windows-7-home-premium-as-a-regular-user
#
# for that reason, we use hardlinks (below), which are allowed to everybody
# Since this would break if files were not on the same partition, we copy _cxxInternal*.pyd
# to a tempdir first (see below). It will still fail on filesystems not supporting hardlinks
# (FAT probably)
def win_symlink(source,link_name):
import ctypes, os.path
csl=ctypes.windll.kernel32.CreateSymbolicLinkW
csl.argtypes=(ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
csl.restype=ctypes.c_ubyte
flags=0
if source is not None and os.path.isdir(source): flags=1
if csl(link_name,source,flags)==0: raise ctypes.WinError()
def win_hardlink(source,link_name):
import ctypes
csl=ctypes.windll.kernel32.CreateHardLinkW
csl.argtypes=(ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_void_p)
csl.restype=ctypes.c_ubyte
if csl(link_name,source,None)==0: raise IOError('Hardlinking failed (files not on the same partition?)')
# enable warnings which are normally invisible, such as DeprecationWarning
warnings.simplefilter('default')
# disable warning for unclosed files/sockets
if PY3K: warnings.simplefilter('ignore',ResourceWarning)
# import eigen before plugins because of its converters, so that default args to python methods can use Vector3r etc
import minieigen
# c++ initialization code
cxxInternalName='_cxxInternal'
if wooOptions.flavor: cxxInternalName+='_'+re.sub('[^a-zA-Z0-9_]','_',wooOptions.flavor)
if wooOptions.debug: cxxInternalName+='_debug'
try:
if not WIN:
_cxxInternal=__import__('woo.'+cxxInternalName,fromlist='woo')
else:
## on windows, copy _cxxInternal*.pyd to the tempdir first, so that we can hardlink to it later
## symlinks are unusable, as they require elevated process (??)
## it must be copied before it gets imported, so we create tempdir ourselves
## and pass it via WOO_TEMP to woo::Master ctor, which will just use it
import tempfile, pkgutil, imp, shutil
tmpdir=wooOsEnviron['WOO_TEMP']=tempfile.mkdtemp(prefix='woo-tmp-')
if not hasattr(sys,'frozen'):
loader=pkgutil.get_loader('woo.'+cxxInternalName)
if not loader: raise ImportError("Unable to get loader for module woo.%s"%cxxInternalName)
pydFile=loader.filename
else:
# frozen install should have full path in sys.argv[0]
pydFile=os.path.dirname(sys.argv[0])+'/woo.'+cxxInternalName+soSuffix
if not os.path.exists(pydFile): raise ImportError("Unable to locate loadable module for woo._cxxInternal in frozen installation: the file %s does not exist"%pydFile)
f=tmpdir+'/'+cxxInternalName+soSuffix
shutil.copy2(pydFile,f)
_cxxInternal=imp.load_dynamic('woo._cxxInternal',f)
pidfile=tmpdir+'/'+'pid'
except ImportError:
print 'Error importing woo.%s (--flavor=%s).'%(cxxInternalName,wooOptions.flavor if wooOptions.flavor else ' ')
#traceback.print_exc()
import glob
sos=glob.glob(re.sub('__init__.py$','',__file__)+'/_cxxInternal_*'+soSuffix)
flavs=[re.sub('(^.*/_cxxInternal_)(.*)(\\'+soSuffix+'$)',r'\2',so) for so in sos]
if sos:
maxFlav=max([len(flav) for flav in flavs])
print 'Available flavors are:'
for so,flav in zip(sos,flavs):
print '\t{0: <{1}}\t{2}'.format(flav,maxFlav,so)
raise
sys.modules['woo._cxxInternal']=_cxxInternal
cxxInternalFile=_cxxInternal.__file__
from . import core
master=core.Master.instance
#
# create compiled python modules
#
if PY3K:
if sys.version_info<(3,4):
print 'WARNING: in Python 3.x, importing only works in Python >= 3.4 properly. Your version %s will most likely break right here.'%(sys.version)
# will only work when http://bugs.python.org/issue16421 is fixed (python 3.4??)
allSubmodules=set()
import imp
for mod in master.compiledPyModules:
if 'WOO_DEBUG' in os.environ: print 'Loading compiled module',mod,'from',cxxInternalFile
# this inserts the module to sys.modules automatically
m=imp.load_dynamic(mod,cxxInternalFile)
# now put the module where it belongs
mm=mod.split('.')
if mm[0]!='woo': print 'ERROR: non-woo module %s imported from the shared lib? Expect troubles.'%mod
elif len(mm)==2:
allSubmodules.add(mm[1])
globals()[mm[1]]=m
else: setattr(eval('.'.join(mm[1:-1])),mm[-1],mm)
else:
# WORKAROUND: create temporary symlinks
def hack_loadCompiledModulesViaLinks(compiledModDir,tryInAnotherTempdir=True):
allSubmodules=set()
import os,sys
if not os.path.exists(compiledModDir): os.mkdir(compiledModDir)
sys.path=[compiledModDir]+sys.path
# move _customConverters to the start, so that imports reyling on respective converters don't fail
# remove woo._cxxInternal since it is imported already
cpm=master.compiledPyModules
cc='woo._customConverters'
#assert cc in cpm # FIXME: temporarily disabled
## HACK: import _gts this way until it gets separated
cpm=[cc]+[m for m in cpm if m!=cc and m!='woo._cxxInternal']
# run imports now
for iMod,mod in enumerate(cpm):
modpath=mod.split('.')
linkName=os.path.join(compiledModDir,modpath[-1])+soSuffix # use just the last part to avoid hierarchy
if WIN:
try:
win_hardlink(os.path.abspath(cxxInternalFile),linkName)
except IOError:
sys.stderr.write('Creating hardlink failed - on Windows, _cxxInternal.pyd is copied to tempdir before being imported, so that hardlinks should be on the same partition. What\'s happening here? If you are using FAT filesystem, you are out of luck. With NTFS, hardlinks should work. Please report this error so that it can be fixed or worked around.\n')
raise
else: os.symlink(os.path.abspath(cxxInternalFile),linkName)
if 'WOO_DEBUG' in os.environ:
print 'Loading compiled module',mod,'from symlink',linkName
print 'modpath =',modpath
sys.stdout.flush()
try: sys.modules[mod]=__import__(modpath[-1])
except ImportError:
# compiled without GTS
if mod=='_gts' and False:
if 'WOO_DEBUG' in os.environ: print 'Loading compiled module _gts: _gts module probably not compiled-in (ImportError)'
pass
else: raise # otherwise it is serious
if len(modpath)==1: pass # nothing to do, adding to sys.modules is enough
if len(modpath)>=2: # subdmodule must be added to module
globals()[modpath[1]]=sys.modules['.'.join(modpath[:2])]
allSubmodules.add(modpath[1])
if len(modpath)>=3: # must be added to module and submodule
setattr(globals()[modpath[1]],modpath[2],sys.modules[mod])
if len(modpath)>=4:
raise RuntimeError('Module %s does not have 2 or 3 path items and will not be imported properly.'%mod)
sys.path=sys.path[1:] # remove temp dir from the path again
return allSubmodules
allSubmodules=hack_loadCompiledModulesViaLinks(master.tmpFilename()) # this will be a directory
# from . import config # does not work in PY3K??
# import woo.config
config=sys.modules['woo.config']
if 'gts' in config.features:
if 'gts' in sys.modules: raise RuntimeError("Woo was compiled with woo.gts; do not import external gts module, they clash with each other.")
from . import gts
# so that it does not get imported twice
sys.modules['gts']=gts
##
## temps cleanup at exit
##
import atexit, shutil, threading, glob
def exitCleanup(path):
#print 'Purging',path
shutil.rmtree(path)
# this would fail under windows anyway
if not WIN:
atexit.register(exitCleanup,master.tmpFileDir)
## clean old temps in bg thread
def cleanOldTemps(prefix,keep):
try: import psutil
except ImportError:
sys.stderr.write('Not cleaning old temps, since the psutil module is missing.\n')
return
for d in glob.glob(prefix+'/woo-tmp-*'):
if d==keep: continue
pidfile=d+'/pid'
if not os.path.exists(pidfile): continue
try:
with open(pidfile) as f: pid=int(f.readlines()[0][:-1])
if not psutil.pid_exists(pid):
sys.stderr.write('Purging old %s (pid=%d)\n'%(d,pid))
shutil.rmtree(d)
except: pass
threading.Thread(target=cleanOldTemps,args=(os.path.dirname(master.tmpFileDir),master.tmpFileDir)).start()
##
## Warn if OpenMP threads are not what is probably expected by the user
##
if wooOptions.ompThreads>1 or wooOptions.ompCores:
if 'openmp' not in config.features:
warnings.warn('--threads and --cores ignored, since compiled without OpenMP.')
elif master.numThreads!=wooOptions.ompThreads:
warnings.warn('--threads/--cores did not set number of OpenMP threads correctly (requested %d, current %d). Was OpenMP initialized in this process already?'%(wooOptions.ompThreads,master.numThreads))
elif master.numThreads>1:
if 'OMP_NUM_THREADS' in os.environ:
if master.numThreads!=int(os.environ['OMP_NUM_THREADS']): warnings.warn('OMP_NUM_THREADS==%s, but woo.master.numThreads==%d'%(os.environ['OMP_NUM_THREADS'],master.numThreads))
else:
warnings.warn('OpenMP is using %d cores without --threads/--cores being used - the default should be 1'%master.numThreads)
if wooOptions.clDev:
if 'opencl' in config.features:
if wooOptions.clDev:
try:
clDev=[int(a) for a in wooOptions.clDev.split(',')]
if len(clDev)==1: clDev.append(-1) # default device
if not len(clDev) in (1,2): raise ValueError()
except (IndexError, ValueError, AssertionError):
raise ValueError('Invalid --cl-dev specification %s, should an integer (platform), or a comma-separated couple (platform,device) of integers'%opts.clDev)
master.defaultClDev=clDev
else: warnings.warn("--cl-dev ignored, since compiled without OpenCL.")
# this import will fail with PY3K??
if not PY3K:
from . import _customConverters
__all__=['master']+list(allSubmodules)
# avoids backtrace if crash at finalization (log4cxx)
from . import system
system.setExitHandlers()
# fake miniEigen being in woo itself
from minieigen import *
# monkey-patches
from . import _monkey
from . import _units
unit=_units.unit # allow woo.unit['mm']
# hint fo pyinstaller to freeze this module
from . import pyderived
# recursive import of everything under wooExtra
try:
# don't import at all if rebuilding (rebuild might fail)
if wooOptions.rebuilding: raise ImportError
import wooExtra
import pkgutil, zipimport
extrasLoaded=[]
for importer, modname, ispkg in pkgutil.iter_modules(wooExtra.__path__):
try:
m=__import__('wooExtra.'+modname,fromlist='wooExtra')
extrasLoaded.append(modname)
if hasattr(sys,'frozen') and not hasattr(m,'__loader__') and len(m.__path__)==1:
zip=m.__path__[0].split('/wooExtra/')[0].split('\\wooExtra\\')[0]
if not (zip.endswith('.zip') or zip.endswith('.egg')):
print 'wooExtra.%s: not a .zip or .egg, no __loader__ set (%s)'%(modname,zip)
else:
print 'wooExtra.%s: setting __loader__ and __file__'%modname
m.__loader__=zipimport.zipimporter(zip)
m.__file__=os.path.join(m.__path__[0],os.path.basename(m.__file__))
except ImportError:
sys.stderr.write('ERROR importing wooExtra.%s:'%modname)
raise
# disable informative message if plain import into python script
if sys.argv[0].split('/')[-1].startswith('woo'): sys.stderr.write('wooExtra modules loaded: %s.\n'%(', '.join(extrasLoaded)))
except ImportError:
# no wooExtra packages are installed
pass
|