~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to wxPython/distrib/wx_conv.py

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Convert modules from the old 'from wxPython.wx import *' style to
 
3
the new 'import wx' style.
 
4
 
 
5
Author: dfh@forestfield.co.uk (David Hughes)
 
6
 
 
7
 
 
8
This should probably go in the tools package and have a startup script
 
9
like the others, but I don't think it's ready for prime-time yet.  So
 
10
just put it in distrib for now so it doesn't get lost...
 
11
 
 
12
--Robin
 
13
"""
 
14
 
 
15
 
 
16
import os, sys, time
 
17
import string
 
18
t0 = time.time()
 
19
 
 
20
 
 
21
import wx
 
22
print 'length = ', len(wx._newnames)
 
23
 
 
24
for key in ['true', 'True', 'false', 'False']:      # use native Python not wx.<bool>
 
25
    if key in wx._newnames:
 
26
        del wx._newnames[key]
 
27
 
 
28
import wx.calendar, wx.gizmos, wx.glcanvas, wx.grid, wx.help, wx.html,   \
 
29
       wx.htmlhelp, wx.iewin, wx.ogl, wx.stc, wx.wizard, wx.xrc
 
30
import wx.lib
 
31
##import wx.lib.activexwrapper, wx.lib.analogclock, wx.lib.anchors,  \
 
32
import wx.lib.activexwrapper,  wx.lib.anchors,  \
 
33
       wx.lib.buttons, wx.lib.calendar, wx.lib.ClickableHtmlWindow,  \
 
34
       wx.lib.colourdb, wx.lib.colourselect, wx.lib.dialogs,   \
 
35
       wx.lib.ErrorDialogs, wx.lib.evtmgr, wx.lib.fancytext,   \
 
36
       wx.lib.filebrowsebutton, wx.lib.gridmovers, wx.lib.grids,  \
 
37
       wx.lib.imagebrowser, wx.lib.imageutils, wx.lib.infoframe,   \
 
38
       wx.lib.intctrl, wx.lib.layoutf, wx.lib.multisash,   \
 
39
       wx.lib.popupctl, wx.lib.printout, wx.lib.rcsizer,   \
 
40
       wx.lib.rightalign, wx.lib.sheet, wx.lib.stattext,   \
 
41
       wx.lib.throbber, wx.lib.timectrl, wx.lib.wxPlotCanvas,   \
 
42
       wx.lib.wxpTag
 
43
import wx.lib.mixins, wx.lib.editor, wx.lib.colourchooser
 
44
import wx.lib.mixins.grid, wx.lib.mixins.imagelist,    \
 
45
       wx.lib.mixins.listctrl
 
46
##       wx.lib.mixins.listctrl, wx.lib.mixins.rubberband
 
47
import wx.lib.editor.editor, wx.lib.editor.images, wx.lib.editor.selection
 
48
import wx.lib.colourchooser.canvas, wx.lib.colourchooser.intl, wx.lib.colourchooser.pycolourbox,   \
 
49
       wx.lib.colourchooser.pycolourchooser, wx.lib.colourchooser.pycolourslider, wx.lib.colourchooser.pypalette
 
50
 
 
51
wxlist = []
 
52
for kd in wx._newnames.items():
 
53
    wxlist.append(kd)
 
54
wxlist.sort()
 
55
 
 
56
n = 0
 
57
for item in wxlist:
 
58
    n += 1
 
59
##    print n, item
 
60
print 'length = ', len(wx._newnames)
 
61
print 'imports completed in ', time.time()-t0, 'secs'
 
62
 
 
63
base_path = 'G:/wxConvert/Test1'
 
64
exclude_dir = ( 'wx', 'wx_cc', 'reportlab', 'sqlite')       # MUST exclude wx if it is below base_dir, others optional
 
65
 
 
66
other_subs = { 'true': 'True',
 
67
               'false': 'False'
 
68
               }
 
69
 
 
70
punct = string.punctuation.replace('_','')                  # exclude single underscore
 
71
punct = punct.replace('.','')                               # and period
 
72
punct = punct.replace('*','')                               # and asterisk, all allowed in names
 
73
punctable = string.maketrans(punct, ' '*len(punct))         # map punctuation characters to spaces
 
74
numfiles = 0
 
75
 
 
76
#----------------------------------------------------------------------------
 
77
 
 
78
class AFile:
 
79
    " file object - collection of properties relating to current instance"
 
80
    def __init__(self, subsdict):
 
81
        self.subsdict = subsdict.copy()     # dictionary of universal and local substitutions to make
 
82
        self.importing = []                 # list of wx modules being imported
 
83
 
 
84
#----------------------------------------------------------------------------
 
85
 
 
86
def visit(noargs, thispath, contentlist):
 
87
    """ Function is called by os walk for every directory in base_path,
 
88
        including base_path itself. Contentlist is a list of files/dirs in thispath.
 
89
        Wx conversion function is called for every qualifying file in list
 
90
    """
 
91
    path = thispath
 
92
    base = 'something'
 
93
    while base:                             # check if thispath or a parent is excluded
 
94
        path, base = os.path.split(path)
 
95
        if base in exclude_dir:
 
96
            print 'Excluded:', thispath
 
97
            return
 
98
 
 
99
    for item in contentlist:
 
100
        pathname = os.path.join(thispath, item)
 
101
        if os.path.isfile(pathname) and pathname[-3:].lower() == '.py':
 
102
            wxconvert(pathname)
 
103
 
 
104
def wxconvert(pathname):
 
105
    """ Scan each line of text in pathname. Replace each occurrence of any key in wx._newnames
 
106
        dictionary with the content stored under that key
 
107
    """
 
108
    global numfiles
 
109
    afile = AFile(other_subs)
 
110
    infile = open(pathname, 'r')
 
111
    linelist = infile.readlines()
 
112
    infile.close()
 
113
 
 
114
    lnum = 0
 
115
    outlist = []
 
116
    for line in linelist:
 
117
        lnum += 1
 
118
        tokenlist = line.replace('.__', ' ').translate(punctable).split()    # split on white space and punctuation
 
119
        line, status = checkimports(afile, line, tokenlist)                  # return line with 'import' modifications
 
120
        if not status:
 
121
            print 'Unable to convert line %d in %s' % (lnum, pathname)
 
122
            break
 
123
        else:
 
124
            for key in afile.subsdict:                    # do other changes first
 
125
                if line.find(key) >= 0:
 
126
                    line = line.replace(key, afile.subsdict[key])
 
127
            for token in tokenlist:                     # change wx names
 
128
                if token in wx._newnames:
 
129
                    candidate = wx._newnames[token]
 
130
                    module = candidate[:candidate.rfind('.')]
 
131
                    if module in afile.importing:
 
132
                        line = line.replace(token, candidate)
 
133
        outlist.append(line)
 
134
    else:
 
135
        outfile = open(pathname, 'w')
 
136
        outfile.writelines(outlist)
 
137
        numfiles += 1
 
138
        print 'Converted:', pathname
 
139
        outfile.close()
 
140
 
 
141
def checkimports(afile, line, tlist):
 
142
    """ Scan tokenlist for wxPython import statement. Add to afile.subsdict any
 
143
        name changes that are necessary for the rest of the current source file.
 
144
        Add to afile.importing any new import modules
 
145
        Return a tuple (status, newstring) -
 
146
           line, possibly modified if an import statmeny
 
147
           status: 0: unable to handle complexity, 1: OK
 
148
    """
 
149
    aline = line
 
150
    if len(tlist) == 0: return (aline, 1)
 
151
    indent = ''
 
152
    for ch in line:
 
153
        if ch in string.whitespace:
 
154
            indent += ' '
 
155
        else:
 
156
            break
 
157
 
 
158
    if tlist[0] == 'import':        # import module [as name] [module [as name]...]
 
159
        skip = False
 
160
        for t in tlist[1:]:
 
161
            if skip:
 
162
                skip = False
 
163
            elif t == 'as':
 
164
                skip = True
 
165
            elif t.startswith('wx'):
 
166
                aline = aline.replace(t, rename_module(afile, t))
 
167
    elif (tlist[0] == 'from' and
 
168
            tlist[1] == 'wxPython' and
 
169
              tlist[2] == 'import'):                # from wxPython import module
 
170
        if len(tlist) > 4:                          # ...[as name] [module [as name]...]
 
171
            return ('', 0)                          # too complicated
 
172
        module = rename_module(afile,tlist[-1])
 
173
        aline = indent = 'import ' + module + '\n'
 
174
    elif (tlist[0] == 'from' and
 
175
            tlist[1].startswith('wxPython') and
 
176
              tlist[2] == 'import'):                # from module import ....
 
177
        if tlist[-1] <> '*':                        # ...name [as name] [name [as name]...]
 
178
            aline = aline.replace(tlist[1], rename_module(afile, tlist[1]))
 
179
            skip = False
 
180
            for t in tlist[3:]:
 
181
                if skip:
 
182
                    skip = False
 
183
                elif t == 'as':
 
184
                    skip = True
 
185
                else:
 
186
                    elem = t.split('.')
 
187
                    if elem[-1].startswith('wx'):           # remove wx prefix from last element of name
 
188
                        elem[-1] = elem[-1][2:]
 
189
                        afile.subsdict[t] = '.'.join(elem)  # and apply to each occurrence in source
 
190
        else:                       # from module import *
 
191
            module = rename_module(afile,tlist[1])
 
192
            aline = indent = 'import ' + module + '\n'
 
193
    return (aline, 1)
 
194
 
 
195
def rename_module(afile, t, type='A'):
 
196
    """ Substitute  wx for wxPython.wx or wx, and wx.foo.bar for wxPython.foo.bar in token
 
197
        foo.bar => wx.foo.bar is also permitted (from wxPython import foo.bar)
 
198
    """
 
199
    if t in ['wx', 'wxPython.wx']:
 
200
        module = 'wx'
 
201
    elif t.startswith('wxPython'):
 
202
        module = t.replace('wxPython', 'wx')
 
203
    elif t.startswith('wx'):
 
204
        module = t
 
205
    else:
 
206
        module = 'wx.' + t
 
207
    if module not in afile.importing:
 
208
        afile.importing.append(module)
 
209
    return module
 
210
 
 
211
def main():
 
212
    " Convert every file in base_dir and all subdirectories except in exclude_dir list"
 
213
 
 
214
    os.path.walk(base_path, visit, None)
 
215
    print '%d files converted in %.2f seconds' % (numfiles, time.time() - t0)
 
216
 
 
217
#----------------------------------------------------------------------------
 
218
 
 
219
if __name__ == '__main__':
 
220
    main()