Package sourceinfo :: Module fileinfo

Source Code for Module sourceinfo.fileinfo

  1  # -*- coding: utf-8 -*- 
  2  """pysourceinfo.fileinfo - information on source files. 
  3   
  4  Based on the stack-frames of *inspect*, *__file__*, and additional  
  5  attributes. 
  6   
  7  Details see manuals. 
  8  """ 
  9  from __future__ import absolute_import 
 10  from __future__ import print_function 
 11   
 12  import os 
 13  import sys 
 14  import re 
 15   
 16  from inspect import stack, getmodule, isbuiltin, ismodule, getsourcefile 
 17   
 18  from pythonids import PYV35Plus 
 19  from sourceinfo import presolve 
 20  from sourceinfo.helper import matchpath, getpythonpath, getpythonpath_rel 
 21   
 22  __author__ = 'Arno-Can Uestuensoez' 
 23  __license__ = "Artistic-License-2.0 + Forced-Fairplay-Constraints" 
 24  __copyright__ = "Copyright (C) 2010-2017 Arno-Can Uestuensoez" \ 
 25      " @Ingenieurbuero Arno-Can Uestuensoez" 
 26  __version__ = '0.1.34' 
 27  __uuid__ = '9de52399-7752-4633-9fdc-66c87a9200b8' 
 28   
 29  __docformat__ = "restructuredtext en" 
 30   
 31   
 32  #--- 
 33  # 
 34  # redundant for autonomous load-independence by reduction of dependencies 
 35  # 
 36  __gmn = re.compile(r'^.*[.]') 
37 -def __getmodule_name(mod):
38 #"""Name similar to basename of loaded module, same as getmodule_oid.""" 39 if mod and ismodule(mod): 40 if hasattr(mod, '__name__'): 41 return __gmn.sub('', mod.__name__)
42 #--- 43
44 -def getcaller_filename(spos=1):
45 """Filename of caller's module. 46 47 Args: 48 spos: 49 Caller position on the stack. 50 51 Returns: 52 Returns the filename. 53 54 Raises: 55 pass-through 56 57 """ 58 return os.path.basename(getcaller_filepathname(spos))
59 60
61 -def getcaller_filepathname(spos=1):
62 """File pathname of caller's module. 63 64 Args: 65 spos: 66 Caller position on the stack. 67 68 Returns: 69 Returns the file pathname. 70 71 Raises: 72 passed through exceptions 73 74 """ 75 _sf = stack() 76 return os.path.abspath(_sf[spos][1])
77 78
79 -def getcaller_filepathname_rel(spos=1):
80 """File pathname of caller's module relative to sys.path.""" 81 _sf = stack() 82 _cf = os.path.abspath(os.path.normpath(_sf[spos][1])) 83 for sx in sys.path: 84 if _cf.startswith(sx): 85 return _cf[len(os.path.normpath(sx))]
86 87
88 -def getcaller_linenumber(spos=1):
89 """Source line number of call. 90 91 Args: 92 spos: 93 Caller position on the stack. 94 95 Returns: 96 Returns the line number of the parent call. 97 98 Raises: 99 pass-through 100 101 """ 102 return stack()[spos][2]
103 104
105 -def getcaller_linenumber_def(spos=1):
106 """First line number of enclosing caller function/method definition. 107 108 Args: 109 spos: 110 Caller position on the stack. 111 112 Returns: 113 Returns the first linenumber of the calling functions/method definition. 114 115 Raises: 116 pass-through 117 118 """ 119 return stack()[spos][0].f_code.co_firstlineno
120
121 -def getcaller_package_filename(spos=1):
122 """ 123 Args: 124 spos: 125 Caller position on the stack. 126 127 Returns: 128 Returns the file name of the package. 129 130 Raises: 131 pass-through 132 133 """ 134 return os.path.basename(getcaller_package_filepathname(spos))
135 136 137 __comp_package_filepathname = re.compile(r""" 138 ( 139 ([/\\\\]*([^/\\\\]+.py)[oc]{0,1}$) 140 | ([/\\\\]*([^/\\\\]+).*.py[oc]{0,1}$) 141 | ([/\\\\]*([^/\\\\]+).*$) 142 ) 143 """, re.VERBOSE # @UndefinedVariable 144 )
145 -def getcaller_package_filepathname(spos=1, pmatch=presolve):
146 """Filepathname of the package from *sys.path*. 147 If not matched by *sys.path* returns the *dirname* of the caller. 148 149 Args: 150 spos: 151 Caller position on the stack. 152 153 Returns: 154 Returns the file path name of the package. 155 156 Raises: 157 pass-through 158 159 """ 160 _sf = stack() 161 _cf = os.path.normpath(os.path.abspath(_sf[spos][1])) 162 p0 = matchpath(_cf, sys.path, pmatch) 163 if not p0: 164 return os.path.dirname(os.path.abspath(_cf)) 165 166 p0l = len(p0) 167 p1 = getcaller_filepathname(spos + 1)[p0l:] 168 pfn = __comp_package_filepathname.search(p1) 169 170 # TODO: PEP420 - Implicit Namespace Packages 171 if pfn.start(2) != -1: 172 return p0 + os.path.sep + pfn.group(3) 173 elif pfn.start(4) != -1: 174 return p0 + os.path.sep + pfn.group(5) 175 elif pfn.start(6) != -1: 176 return p0 + os.path.sep + pfn.group(7) 177 return None
178 179
180 -def getcaller_package_pathname(spos=1, pmatch=presolve):
181 """Pathname of the package from *sys.path* as used for search of the package. 182 Relies on 'inspect'. 183 184 Args: 185 spos: 186 Caller position on the stack.__ 187 188 Returns: 189 Returns the path name to the package. 190 191 Raises: 192 pass-through 193 194 """ 195 return os.path.dirname(getcaller_package_filepathname(spos+1, pmatch))
196 197
198 -def getcaller_pathname(spos=1):
199 """pathname of caller source file. 200 201 Args: 202 spos: 203 Caller position on the stack. 204 205 Returns: 206 Returns the filename. 207 208 Raises: 209 pass-through 210 211 """ 212 if not PYV35Plus: 213 return os.path.dirname(getcaller_filepathname(spos + 1)) 214 else: 215 _sf = stack() 216 # mx = _sf[spos][0].f_locals['module'] 217 module = getmodule(_sf[spos][0]) 218 if hasattr(module, '__file__'): 219 f = module.__file__ 220 return os.path.dirname(f)
221 # PEP 3147 -- PYC Repository Directories 222 223 224 __comp_getcaller_pathname_rel = re.compile(r""" 225 ( 226 (()[/\\\\]*[^/\\\\]+.py[oc]{0,1}$) 227 |([/\\\\]*(.+)[/\\\\][^/\\\\]+.py[oc]{0,1}$) 228 |([/\\\\]*(.+)) 229 ) 230 """, re.VERBOSE # @UndefinedVariable 231 ) 232 233
234 -def getcaller_pathname_rel(spos=1):
235 """Relative pathname to first matching package directory of caller. 236 Evaluates 'sys.path' first, else switches to 'inspect'. 237 238 Args: 239 spos: 240 Caller position on the stack. 241 242 Returns: 243 Returns the path name to the package. 244 245 Raises: 246 pass-through 247 248 """ 249 ax = os.path.normpath(getcaller_filepathname( 250 spos + 1)) # TODO: check for normpath 251 for si in sys.path: 252 si = os.path.normpath(si) 253 if ax.startswith(si): 254 gx = __comp_getcaller_pathname_rel.search(ax[len(si):]) 255 if gx.start(3) != -1: 256 return gx.group(3) 257 elif gx.start(5) != -1: 258 return gx.group(5) 259 elif gx.start(7) != -1: 260 return gx.group(7) 261 return None
262 263
264 -def getcaller_pathname_sub(spos=1):
265 """sub-pathname to first matching module directory of caller. 266 Evaluates 'sys.path' first, else switches to 'inspect'. 267 268 Args: 269 spos: 270 Caller position on the stack. 271 272 Returns: 273 Returns the path name to the package. 274 275 Raises: 276 pass-through 277 278 """ 279 return re.sub(r"[^/\\\\]*[/\\\\](.*)", r"\1", getcaller_pathname_rel(spos + 1))
280 281
282 -def getcaller_python_pathname(spos=1):
283 """Alias for getcaller_package_pathname 284 285 Args: 286 spos: 287 Caller position on the stack. 288 289 Returns: 290 Returns the name of caller module. 291 292 Raises: 293 passed through exceptions 294 295 """ 296 return getcaller_package_pathname(spos + 1)
297 298
299 -def getcaller_source_filepathname(spos=1):
300 """Pathname of caller source. 301 302 Args: 303 spos: 304 Caller position on the stack. 305 306 Returns: 307 Returns the file pathname of the source for the caller, 308 else None. 309 310 Raises: 311 pass-through 312 313 """ 314 return os.path.abspath(getsourcefile(stack()[spos][0])) # mx = _sf[spos][1]
315 316
317 -def getmodule_filename(mod):
318 """Basename of file for loaded module *mod*. 319 320 Args: 321 mod: 322 Reference to a loaded module. 323 324 Returns: 325 Returns the basename of the loaded module. 326 327 Raises: 328 pass-through 329 330 """ 331 if mod and ismodule(mod) and not isbuiltin(mod): 332 if hasattr(mod, '__file__') and os.path.exists(mod.__file__): 333 return os.path.basename(mod.__file__)
334 335
336 -def getmodule_filepathname(mod):
337 """File pathname of loaded module *mod*. 338 339 Args: 340 mod: 341 Reference to a loaded module. 342 343 Returns: 344 Returns the file pathname of the loaded module. 345 346 Raises: 347 pass-through 348 349 """ 350 if mod and ismodule(mod) and not isbuiltin(mod): 351 return os.path.abspath(getsourcefile(mod))
352 353
354 -def getmodule_package_pathname(mod):
355 """Path name of package for loaded module. 356 357 Args: 358 mod: 359 Reference to a loaded module. 360 361 Returns: 362 Returns the pathname of the package. 363 364 Raises: 365 pass-through 366 367 """ 368 mn = __getmodule_name(mod) # requires normalized path 369 if mn: 370 mpn = getmodule_pathname(mod) 371 return mpn[:len(mpn) + 1]
372 373
374 -def getmodule_pathname(mod):
375 """Path name of loaded module. 376 377 Args: 378 mod: 379 Reference to a loaded module. 380 381 Returns: 382 Returns the pathname of the loaded module. 383 384 Raises: 385 pass-through 386 387 """ 388 if mod and ismodule(mod) and not isbuiltin(mod): 389 if hasattr(mod, '__file__'): 390 return os.path.normpath(os.path.dirname(mod.__file__))
391 392
393 -def getmodule_pathname_rel(mod, plist=None):
394 """Relative path name to PYTHONPATH for loaded module. 395 396 Args: 397 mod: 398 Reference to a loaded module. 399 400 Returns: 401 Returns the relative pathname of the loaded module. 402 403 Raises: 404 pass-through 405 406 """ 407 if mod and ismodule(mod) and not isbuiltin(mod): 408 if hasattr(mod, '__file__'): 409 return getpythonpath_rel(mod.__file__, plist)
410 411
412 -def getmodule_pathname_sub(mod, plist=None):
413 """Path name for loaded module, relative to package path. 414 415 Args: 416 mod: 417 Reference to a loaded module. 418 419 Returns: 420 Returns the sub pathname of the loaded module. 421 422 Raises: 423 pass-through 424 425 """ 426 ax = getmodule_pathname_rel(mod, plist) 427 if not PYV35Plus: 428 return re.sub(r"[^/\\\\]*[/\\\\]", r"\1", ax) 429 else: 430 return re.sub(r"[^/\\\\]*[/\\\\]".encode('utf-8'), r"\1".encode('utf-8'), ax)
431 432
433 -def getmodule_python_pathname(mod, plist=None):
434 """Path name from PYTHONPATH of loaded module. 435 436 Args: 437 mod: 438 Reference to a loaded module. 439 440 Returns: 441 Returns the pathname of the loaded module. 442 443 Raises: 444 pass-through 445 446 """ 447 if mod and ismodule(mod) and not isbuiltin(mod): 448 if hasattr(mod, '__file__'): 449 return getpythonpath(mod.__file__, plist)
450