#! /usr/bin/env python # pdeps # # Find dependencies between a bunch of Python modules. # # Usage: # pdeps file1.py file2.py ... # # Output: # Four tables separated by lines like '--- Closure ---': # 1) Direct dependencies, listing which module imports which other modules # 2) The inverse of (1) # 3) Indirect dependencies, or the closure of the above # 4) The inverse of (3) # # To do: # - command line options to select output type # - option to automatically scan the Python library for referenced modules # - option to limit output to particular modules import sys import re import os # Main program # def main(): args = sys.argv[1:] if not args: print 'usage: pdeps file.py file.py ...' return 2 # table = {} for arg in args: process(arg, table) # print '--- Uses ---' printresults(table) # print '--- Used By ---' inv = inverse(table) printresults(inv) # print '--- Closure of Uses ---' reach = closure(table) printresults(reach) # print '--- Closure of Used By ---' invreach = inverse(reach) printresults(invreach) # return 0 # Compiled regular expressions to search for import statements # m_import = re.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+') m_from = re.compile('^[ \t]*import[ \t]+([^#]+)') # Collect data from one file # def process(filename, table): fp = open(filename, 'r') mod = os.path.basename(filename) if mod[-3:] == '.py': mod = mod[:-3] table[mod] = list = [] while 1: line = fp.readline() if not line: break while line[-1:] == '\\': nextline = fp.readline() if not nextline: break line = line[:-1] + nextline if m_import.match(line) >= 0: (a, b), (a1, b1) = m_import.regs[:2] elif m_from.match(line) >= 0: (a, b), (a1, b1) = m_from.regs[:2] else: continue words = line[a1:b1].split(',') # print '#', line, words for word in words: word = word.strip() if word not in list: list.append(word) # Compute closure (this is in fact totally general) # def closure(table): modules = table.keys() # # Initialize reach with a copy of table # reach = {} for mod in modules: reach[mod] = table[mod][:] # # Iterate until no more change # change = 1 while change: change = 0 for mod in modules: for mo in reach[mod]: if mo in modules: for m in reach[mo]: if m not in reach[mod]: reach[mod].append(m) change = 1 # return reach # Invert a table (this is again totally general). # All keys of the original table are made keys of the inverse, # so there may be empty lists in the inverse. # def inverse(table): inv = {} for key in table.keys(): if not inv.has_key(key): inv[key] = [] for item in table[key]: store(inv, item, key) return inv # Store "item" in "dict" under "key". # The dictionary maps keys to lists of items. # If there is no list for the key yet, it is created. # def store(dict, key, item): if dict.has_key(key): dict[key].append(item) else: dict[key] = [item] # Tabulate results neatly # def printresults(table): modules = table.keys() maxlen = 0 for mod in modules: maxlen = max(maxlen, len(mod)) modules.sort() for mod in modules: list = table[mod] list.sort() print mod.ljust(maxlen), ':', if mod in list: print '(*)', for ref in list: print ref, print # Call main and honor exit status if __name__ == '__main__': try: sys.exit(main()) except KeyboardInterrupt: sys.exit(1) : 'ia32', 'x86' : 'ia32', --- 101,108 ---- valid_abis = {'ia32' : 'ia32', 'x86' : 'ia32', 'ia64' : 'ia64', ! 'em64t' : 'em64t', ! 'amd64' : 'em64t'} if is_linux: valid_abis = {'ia32' : 'ia32', 'x86' : 'ia32', ................ r2993 | stevenknight | 2008-05-27 16:22:35 -0700 (Tue, 27 May 2008) | 3 lines Issue 2062: Fix --interactive mode getting "stuck" reporting failures for every build after the first one that fails. ................ r2997 | stevenknight | 2008-05-28 18:18:36 -0700 (Wed, 28 May 2008) | 4 lines Fix the closing message on interrupt to report "building terminated because of errors." Add a missing test.pass_test() call to the end of test/KeyboardInterrupt.py. ................ r2998 | stevenknight | 2008-05-29 08:14:47 -0700 (Thu, 29 May 2008) | 2 lines Issue 2075: Fix the ability to call the Node.FS.File.File() method. ................ r2999 | stevenknight | 2008-05-29 14:12:07 -0700 (Thu, 29 May 2008) | 2 lines Issue 2063: On Mac OS X, install under /usr/local by default. ................ r3017 | stevenknight | 2008-05-30 08:05:26 -0700 (Fri, 30 May 2008) | 3 lines Get the fix for File.File() right this time. Apply the same fix to File.Dir() and File.Entry(), too. ................ r3022 | stevenknight | 2008-06-02 18:52:42 -0700 (Mon, 02 Jun 2008) | 3 lines Fix "deprecated conversion from string constant to char *" warnings in various C++ tests. ................ r3045 | garyo | 2008-06-05 06:05:37 -0700 (Thu, 05 Jun 2008) | 8 lines This fix uses Python sequence comparison to compare the dotted version numbers used in .NET version numbers rather than comparing each element of the list individually. It's more robust and also more correct. I also fixed a Python 1.5.2 compatibility issue (strings didn't have the split method). Original reporter confirms this fixes his issue. ................ r3046 | garyo | 2008-06-05 20:35:27 -0700 (Thu, 05 Jun 2008) | 1 line Minor doc tweaks to Users Guide. ................ r3050 | stevenknight | 2008-06-06 11:38:38 -0700 (Fri, 06 Jun 2008) | 21 lines Merged revisions 2877,2879-2978,2980-3019,3021-3048 via svnmerge from http://scons.tigris.org/svn/scons/branches/fortran_refactor ........ r2980 | cournape | 2008-05-23 21:56:19 -0700 (Fri, 23 May 2008) | 1 line Emit a warning and use as a linker when fortran and c++ codes are mixed. ........ r3000 | cournape | 2008-05-29 21:29:37 -0700 (Thu, 29 May 2008) | 1 line Improve warning when mixing c++ and fortran. ........ r3048 | stevenknight | 2008-06-06 11:30:25 -0700 (Fri, 06 Jun 2008) | 6 lines Issue 2047: update the warning text to make it less alarming. Move the warning classes so they can be suppressed. Add a test of the warning (and suppression) behavior Only issue one warning per SCons invocation, not one per built executable. Update CHANGES.txt and RELEASE.txt. ........ ................ r3051 | stevenknight | 2008-06-07 08:11:46 -0700 (Sat, 07 Jun 2008) | 3 lines Fix the Fortran/C++ link test for deprecation warnings under earlier Python version. ................ r3052 | stevenknight | 2008-06-07 08:12:22 -0700 (Sat, 07 Jun 2008) | 2 lines Add Benoit's EMT64 change that will be released in 0.98.5. ................ r3053 | stevenknight | 2008-06-07 08:21:50 -0700 (Sat, 07 Jun 2008) | 2 lines Update lines for 0.98.5 release. ................ r3054 | stevenknight | 2008-06-07 08:26:04 -0700 (Sat, 07 Jun 2008) | 2 lines Update 0.98.4 versions to 0.98.5. ................
http://scons.tigris.org/svn/scons/branches/core

................
  r2955 | stevenknight | 2008-05-18 07:48:43 -0700 (Sun, 18 May 2008) | 2 lines

  Update lines for next development cycle.
................
  r2956 | GregNoel | 2008-05-19 14:24:39 -0700 (Mon, 19 May 2008) | 1 line

  Fix typo in Mkdir() description
................
  r2957 | cournape | 2008-05-19 22:37:17 -0700 (Mon, 19 May 2008) | 1 line

  sunc++ tool: do not parse pkgchk output if no output available (Fix for #2060).
................
  r2958 | cournape | 2008-05-19 23:34:01 -0700 (Mon, 19 May 2008) | 6 lines


  Do not set cppcPath to CXX if CXX has no dirname. This caused weird behaviour,
  because cppcPath and cxx were joined together, and scons used things like CC/CC
  as CXX.
................
  r2960 | cournape | 2008-05-20 22:23:12 -0700 (Tue, 20 May 2008) | 3 lines

  Initialized merge tracking via "svnmerge" with revisions "1-2959" from
  http://scons.tigris.org/svn/scons/branches/pyext
................
  r2971 | stevenknight | 2008-05-22 16:01:11 -0700 (Thu, 22 May 2008) | 4 lines

  Issue 2056:  Fix scons.bat so that it returns the SCons exit status even
  though we're using setlocal + endlocal to avoid polluting the calling
  user's %PATH% variable.
................
  r2972 | stevenknight | 2008-05-22 16:35:00 -0700 (Thu, 22 May 2008) | 2 lines

  Move generic windows tests from the test/ subdirectory into test/Win32.
................
  r2973 | stevenknight | 2008-05-22 18:58:35 -0700 (Thu, 22 May 2008) | 2 lines

  Fix scoping under Python 1.5 / 2.0 / 2.1.
................
  r2976 | cournape | 2008-05-23 04:10:37 -0700 (Fri, 23 May 2008) | 3 lines

  Initialized merge tracking via "svnmerge" with revisions "1-2975" from
  http://scons.tigris.org/svn/scons/branches/libwithcontext
................
  r2978 | GregNoel | 2008-05-23 12:39:42 -0700 (Fri, 23 May 2008) | 1 line

  script to convert XML issues into CSV spreadsheet
................
  r2987 | GregNoel | 2008-05-25 10:57:14 -0700 (Sun, 25 May 2008) | 1 line

  trivial typo
................
  r2989 | pankrat | 2008-05-25 14:42:53 -0700 (Sun, 25 May 2008) | 3 lines

  Initialized merge tracking via "svnmerge" with revisions "1-2988" from
  http://scons.tigris.org/svn/scons/branches/heapmonitor
................
  r2992 | belley | 2008-05-27 08:23:34 -0700 (Tue, 27 May 2008) | 41 lines

  Fixed the detection of Intel C++ Compiler for EMT64

  The table used to check the registry keys for installed versions of
  the Intel C++ compiler for EMT64 seems erroneous. I have double check
  using the Intel C++ compiler versions 9.1 and 10.0 on both Windows XP
  32-bit and Windows Server2003 64-bits.

  The registry keys have the form

  HKEY_LOCAL_MACHINE\SOFTWARE\INTEL\Compilers\C++\100.025\IA32
  HKEY_LOCAL_MACHINE\SOFTWARE\INTEL\Compilers\C++\100.025\IA64
  HKEY_LOCAL_MACHINE\SOFTWARE\INTEL\Compilers\C++\100.025\EMT64

  Benoit


  Index: src/engine/SCons/Tool/intelc.py
  ===================================================================
  *** src/engine/SCons/Tool/intelc.py	(revision 2991)
  --- src/engine/SCons/Tool/intelc.py	(working copy)
  ***************
  *** 101,108 ****
            valid_abis = {'ia32'  : 'ia32',
                          'x86'   : 'ia32',
                          'ia64'  : 'ia64',
  !                       'em64t' : 'ia32e',
  !                       'amd64' : 'ia32e'}
        if is_linux:
            valid_abis = {'ia32'   : 'ia32',
                          'x86'    : 'ia32',
  --- 101,108 ----
            valid_abis = {'ia32'  : 'ia32',
                          'x86'   : 'ia32',
                          'ia64'  : 'ia64',
  !                       'em64t' : 'em64t',
  !                       'amd64' : 'em64t'}
        if is_linux:
            valid_abis = {'ia32'   : 'ia32',
                          'x86'    : 'ia32',
................
  r2993 | stevenknight | 2008-05-27 16:22:35 -0700 (Tue, 27 May 2008) | 3 lines

  Issue 2062:  Fix --interactive mode getting "stuck" reporting failures
  for every build after the first one that fails.
................
  r2997 | stevenknight | 2008-05-28 18:18:36 -0700 (Wed, 28 May 2008) | 4 lines

  Fix the closing message on interrupt to report "building terminated
  because of errors."  Add a missing test.pass_test() call to the
  end of test/KeyboardInterrupt.py.
................
  r2998 | stevenknight | 2008-05-29 08:14:47 -0700 (Thu, 29 May 2008) | 2 lines

  Issue 2075:  Fix the ability to call the Node.FS.File.File() method.
................
  r2999 | stevenknight | 2008-05-29 14:12:07 -0700 (Thu, 29 May 2008) | 2 lines

  Issue 2063:  On Mac OS X, install under /usr/local by default.
................
  r3017 | stevenknight | 2008-05-30 08:05:26 -0700 (Fri, 30 May 2008) | 3 lines

  Get the fix for File.File() right this time.  Apply the same fix
  to File.Dir() and File.Entry(), too.
................
  r3022 | stevenknight | 2008-06-02 18:52:42 -0700 (Mon, 02 Jun 2008) | 3 lines

  Fix "deprecated conversion from string constant to char *" warnings in
  various C++ tests.
................
  r3045 | garyo | 2008-06-05 06:05:37 -0700 (Thu, 05 Jun 2008) | 8 lines

  This fix uses Python sequence comparison to compare the dotted version
  numbers used in .NET version numbers rather than comparing each
  element of the list individually.  It's more robust and also more
  correct.  I also fixed a Python 1.5.2 compatibility issue (strings
  didn't have the split method).

  Original reporter confirms this fixes his issue.
................
  r3046 | garyo | 2008-06-05 20:35:27 -0700 (Thu, 05 Jun 2008) | 1 line

  Minor doc tweaks to Users Guide.
................
  r3050 | stevenknight | 2008-06-06 11:38:38 -0700 (Fri, 06 Jun 2008) | 21 lines

  Merged revisions 2877,2879-2978,2980-3019,3021-3048 via svnmerge from
  http://scons.tigris.org/svn/scons/branches/fortran_refactor

  ........
    r2980 | cournape | 2008-05-23 21:56:19 -0700 (Fri, 23 May 2008) | 1 line

    Emit a warning and use  as a linker when fortran and c++ codes are mixed.
  ........
    r3000 | cournape | 2008-05-29 21:29:37 -0700 (Thu, 29 May 2008) | 1 line

    Improve warning when mixing c++ and fortran.
  ........
    r3048 | stevenknight | 2008-06-06 11:30:25 -0700 (Fri, 06 Jun 2008) | 6 lines

    Issue 2047:  update the warning text to make it less alarming.
    Move the warning classes so they can be suppressed.
    Add a test of the warning (and suppression) behavior
    Only issue one warning per SCons invocation, not one per built executable.
    Update CHANGES.txt and RELEASE.txt.
  ........
................
  r3051 | stevenknight | 2008-06-07 08:11:46 -0700 (Sat, 07 Jun 2008) | 3 lines

  Fix the Fortran/C++ link test for deprecation warnings
  under earlier Python version.
................
  r3052 | stevenknight | 2008-06-07 08:12:22 -0700 (Sat, 07 Jun 2008) | 2 lines

  Add Benoit's EMT64 change that will be released in 0.98.5.
................
  r3053 | stevenknight | 2008-06-07 08:21:50 -0700 (Sat, 07 Jun 2008) | 2 lines

  Update lines for 0.98.5 release.
................
  r3054 | stevenknight | 2008-06-07 08:26:04 -0700 (Sat, 07 Jun 2008) | 2 lines

  Update 0.98.4 versions to 0.98.5.
................