git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21593 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			221 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""
 | 
						|
Convert modules from the old 'from wxPython.wx import *' style to
 | 
						|
the new 'import wx' style.
 | 
						|
 | 
						|
Author: dfh@forestfield.co.uk (David Hughes)
 | 
						|
 | 
						|
 | 
						|
This should probably go in the tools package and have a startup script
 | 
						|
like the others, but I don't think it's ready for prime-time yet.  So
 | 
						|
just put it in distrib for now so it doesn't get lost...
 | 
						|
 | 
						|
--Robin
 | 
						|
"""
 | 
						|
 | 
						|
 | 
						|
import os, sys, time
 | 
						|
import string
 | 
						|
t0 = time.time()
 | 
						|
 | 
						|
 | 
						|
import wx
 | 
						|
print 'length = ', len(wx._newnames)
 | 
						|
 | 
						|
for key in ['true', 'True', 'false', 'False']:      # use native Python not wx.<bool>
 | 
						|
    if key in wx._newnames:
 | 
						|
        del wx._newnames[key]
 | 
						|
 | 
						|
import wx.calendar, wx.gizmos, wx.glcanvas, wx.grid, wx.help, wx.html,   \
 | 
						|
       wx.htmlhelp, wx.iewin, wx.ogl, wx.stc, wx.wizard, wx.xrc
 | 
						|
import wx.lib
 | 
						|
##import wx.lib.activexwrapper, wx.lib.analogclock, wx.lib.anchors,  \
 | 
						|
import wx.lib.activexwrapper,  wx.lib.anchors,  \
 | 
						|
       wx.lib.buttons, wx.lib.calendar, wx.lib.ClickableHtmlWindow,  \
 | 
						|
       wx.lib.colourdb, wx.lib.colourselect, wx.lib.dialogs,   \
 | 
						|
       wx.lib.ErrorDialogs, wx.lib.evtmgr, wx.lib.fancytext,   \
 | 
						|
       wx.lib.filebrowsebutton, wx.lib.gridmovers, wx.lib.grids,  \
 | 
						|
       wx.lib.imagebrowser, wx.lib.imageutils, wx.lib.infoframe,   \
 | 
						|
       wx.lib.intctrl, wx.lib.layoutf, wx.lib.multisash,   \
 | 
						|
       wx.lib.popupctl, wx.lib.printout, wx.lib.rcsizer,   \
 | 
						|
       wx.lib.rightalign, wx.lib.sheet, wx.lib.stattext,   \
 | 
						|
       wx.lib.throbber, wx.lib.timectrl, wx.lib.wxPlotCanvas,   \
 | 
						|
       wx.lib.wxpTag
 | 
						|
import wx.lib.mixins, wx.lib.editor, wx.lib.colourchooser
 | 
						|
import wx.lib.mixins.grid, wx.lib.mixins.imagelist,    \
 | 
						|
       wx.lib.mixins.listctrl
 | 
						|
##       wx.lib.mixins.listctrl, wx.lib.mixins.rubberband
 | 
						|
import wx.lib.editor.editor, wx.lib.editor.images, wx.lib.editor.selection
 | 
						|
import wx.lib.colourchooser.canvas, wx.lib.colourchooser.intl, wx.lib.colourchooser.pycolourbox,   \
 | 
						|
       wx.lib.colourchooser.pycolourchooser, wx.lib.colourchooser.pycolourslider, wx.lib.colourchooser.pypalette
 | 
						|
 | 
						|
wxlist = []
 | 
						|
for kd in wx._newnames.items():
 | 
						|
    wxlist.append(kd)
 | 
						|
wxlist.sort()
 | 
						|
 | 
						|
n = 0
 | 
						|
for item in wxlist:
 | 
						|
    n += 1
 | 
						|
##    print n, item
 | 
						|
print 'length = ', len(wx._newnames)
 | 
						|
print 'imports completed in ', time.time()-t0, 'secs'
 | 
						|
 | 
						|
base_path = 'G:/wxConvert/Test1'
 | 
						|
exclude_dir = ( 'wx', 'wx_cc', 'reportlab', 'sqlite')       # MUST exclude wx if it is below base_dir, others optional
 | 
						|
 | 
						|
other_subs = { 'true': 'True',
 | 
						|
               'false': 'False'
 | 
						|
               }
 | 
						|
 | 
						|
punct = string.punctuation.replace('_','')                  # exclude single underscore
 | 
						|
punct = punct.replace('.','')                               # and period
 | 
						|
punct = punct.replace('*','')                               # and asterisk, all allowed in names
 | 
						|
punctable = string.maketrans(punct, ' '*len(punct))         # map punctuation characters to spaces
 | 
						|
numfiles = 0
 | 
						|
 | 
						|
#----------------------------------------------------------------------------
 | 
						|
 | 
						|
class AFile:
 | 
						|
    " file object - collection of properties relating to current instance"
 | 
						|
    def __init__(self, subsdict):
 | 
						|
        self.subsdict = subsdict.copy()     # dictionary of universal and local substitutions to make
 | 
						|
        self.importing = []                 # list of wx modules being imported
 | 
						|
 | 
						|
#----------------------------------------------------------------------------
 | 
						|
 | 
						|
def visit(noargs, thispath, contentlist):
 | 
						|
    """ Function is called by os walk for every directory in base_path,
 | 
						|
        including base_path itself. Contentlist is a list of files/dirs in thispath.
 | 
						|
        Wx conversion function is called for every qualifying file in list
 | 
						|
    """
 | 
						|
    path = thispath
 | 
						|
    base = 'something'
 | 
						|
    while base:                             # check if thispath or a parent is excluded
 | 
						|
        path, base = os.path.split(path)
 | 
						|
        if base in exclude_dir:
 | 
						|
            print 'Excluded:', thispath
 | 
						|
            return
 | 
						|
 | 
						|
    for item in contentlist:
 | 
						|
        pathname = os.path.join(thispath, item)
 | 
						|
        if os.path.isfile(pathname) and pathname[-3:].lower() == '.py':
 | 
						|
            wxconvert(pathname)
 | 
						|
 | 
						|
def wxconvert(pathname):
 | 
						|
    """ Scan each line of text in pathname. Replace each occurrence of any key in wx._newnames
 | 
						|
        dictionary with the content stored under that key
 | 
						|
    """
 | 
						|
    global numfiles
 | 
						|
    afile = AFile(other_subs)
 | 
						|
    infile = open(pathname, 'r')
 | 
						|
    linelist = infile.readlines()
 | 
						|
    infile.close()
 | 
						|
 | 
						|
    lnum = 0
 | 
						|
    outlist = []
 | 
						|
    for line in linelist:
 | 
						|
        lnum += 1
 | 
						|
        tokenlist = line.replace('.__', ' ').translate(punctable).split()    # split on white space and punctuation
 | 
						|
        line, status = checkimports(afile, line, tokenlist)                  # return line with 'import' modifications
 | 
						|
        if not status:
 | 
						|
            print 'Unable to convert line %d in %s' % (lnum, pathname)
 | 
						|
            break
 | 
						|
        else:
 | 
						|
            for key in afile.subsdict:                    # do other changes first
 | 
						|
                if line.find(key) >= 0:
 | 
						|
                    line = line.replace(key, afile.subsdict[key])
 | 
						|
            for token in tokenlist:                     # change wx names
 | 
						|
                if token in wx._newnames:
 | 
						|
                    candidate = wx._newnames[token]
 | 
						|
                    module = candidate[:candidate.rfind('.')]
 | 
						|
                    if module in afile.importing:
 | 
						|
                        line = line.replace(token, candidate)
 | 
						|
        outlist.append(line)
 | 
						|
    else:
 | 
						|
        outfile = open(pathname, 'w')
 | 
						|
        outfile.writelines(outlist)
 | 
						|
        numfiles += 1
 | 
						|
        print 'Converted:', pathname
 | 
						|
        outfile.close()
 | 
						|
 | 
						|
def checkimports(afile, line, tlist):
 | 
						|
    """ Scan tokenlist for wxPython import statement. Add to afile.subsdict any
 | 
						|
        name changes that are necessary for the rest of the current source file.
 | 
						|
        Add to afile.importing any new import modules
 | 
						|
        Return a tuple (status, newstring) -
 | 
						|
           line, possibly modified if an import statmeny
 | 
						|
           status: 0: unable to handle complexity, 1: OK
 | 
						|
    """
 | 
						|
    aline = line
 | 
						|
    if len(tlist) == 0: return (aline, 1)
 | 
						|
    indent = ''
 | 
						|
    for ch in line:
 | 
						|
        if ch in string.whitespace:
 | 
						|
            indent += ' '
 | 
						|
        else:
 | 
						|
            break
 | 
						|
 | 
						|
    if tlist[0] == 'import':        # import module [as name] [module [as name]...]
 | 
						|
        skip = False
 | 
						|
        for t in tlist[1:]:
 | 
						|
            if skip:
 | 
						|
                skip = False
 | 
						|
            elif t == 'as':
 | 
						|
                skip = True
 | 
						|
            elif t.startswith('wx'):
 | 
						|
                aline = aline.replace(t, rename_module(afile, t))
 | 
						|
    elif (tlist[0] == 'from' and
 | 
						|
            tlist[1] == 'wxPython' and
 | 
						|
              tlist[2] == 'import'):                # from wxPython import module
 | 
						|
        if len(tlist) > 4:                          # ...[as name] [module [as name]...]
 | 
						|
            return ('', 0)                          # too complicated
 | 
						|
        module = rename_module(afile,tlist[-1])
 | 
						|
        aline = indent = 'import ' + module + '\n'
 | 
						|
    elif (tlist[0] == 'from' and
 | 
						|
            tlist[1].startswith('wxPython') and
 | 
						|
              tlist[2] == 'import'):                # from module import ....
 | 
						|
        if tlist[-1] <> '*':                        # ...name [as name] [name [as name]...]
 | 
						|
            aline = aline.replace(tlist[1], rename_module(afile, tlist[1]))
 | 
						|
            skip = False
 | 
						|
            for t in tlist[3:]:
 | 
						|
                if skip:
 | 
						|
                    skip = False
 | 
						|
                elif t == 'as':
 | 
						|
                    skip = True
 | 
						|
                else:
 | 
						|
                    elem = t.split('.')
 | 
						|
                    if elem[-1].startswith('wx'):           # remove wx prefix from last element of name
 | 
						|
                        elem[-1] = elem[-1][2:]
 | 
						|
                        afile.subsdict[t] = '.'.join(elem)  # and apply to each occurrence in source
 | 
						|
        else:                       # from module import *
 | 
						|
            module = rename_module(afile,tlist[1])
 | 
						|
            aline = indent = 'import ' + module + '\n'
 | 
						|
    return (aline, 1)
 | 
						|
 | 
						|
def rename_module(afile, t, type='A'):
 | 
						|
    """ Substitute  wx for wxPython.wx or wx, and wx.foo.bar for wxPython.foo.bar in token
 | 
						|
        foo.bar => wx.foo.bar is also permitted (from wxPython import foo.bar)
 | 
						|
    """
 | 
						|
    if t in ['wx', 'wxPython.wx']:
 | 
						|
        module = 'wx'
 | 
						|
    elif t.startswith('wxPython'):
 | 
						|
        module = t.replace('wxPython', 'wx')
 | 
						|
    elif t.startswith('wx'):
 | 
						|
        module = t
 | 
						|
    else:
 | 
						|
        module = 'wx.' + t
 | 
						|
    if module not in afile.importing:
 | 
						|
        afile.importing.append(module)
 | 
						|
    return module
 | 
						|
 | 
						|
def main():
 | 
						|
    " Convert every file in base_dir and all subdirectories except in exclude_dir list"
 | 
						|
 | 
						|
    os.path.walk(base_path, visit, None)
 | 
						|
    print '%d files converted in %.2f seconds' % (numfiles, time.time() - t0)
 | 
						|
 | 
						|
#----------------------------------------------------------------------------
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    main()
 |