wxWidgets/wxPython/distrib/wx_conv.py

221 lines
8.5 KiB
Python
Raw Normal View History

"""
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()