I have a bunch of long pyqt scripts, in which the original author wrote code like this
from PyQt4.QtGui import *
from PyQt4.QtCore import *
...
Is there a smart or quick way to change the code to
from PyQt4 import QtGui,QtCore
...
and also prefix every pyqt class with module name? eg
change QDialog to QtGui.QDialog, with sublime editor or pycharm ? or any other editor?
I read about one can add custom fixers to 2to3 script, and repurpose that tool for this, but that doesn't seem a simple task. Or build ast tree and do the replace by yourself ( sounds more complex and maybe it is reinventing the wheel ). Or should I just write regex replace script and just parse all the .py files ? ( sounds unsafe )
edit: I read the original question, it seems my question is a subset of it, finally I used a hacky solution, since I knew the code I want to fix is pyqt.
bad_file = '/path/to/bad_file'
import re
from PyQt4 import QtCore,QtGui
QtCore_mappings = [x for x in dir(QtCore) if '_' not in x]
QtGui_mappings = [x for x in dir(QtGui) if '_' not in x]
mappings = {'QtCore':QtCore_mappings,'QtGui':QtGui_mappings }
cache={}
def find_class_long_name(c):
for k,v in mappings.iteritems():
if c in v:
return '%s.%s' % (k,c)
else:
return None
with open(bad_file) as f:
code = f.read()
all_classes = re.findall(r'\bQ[A-Z]\w*\b', code)
all_classes=set(all_classes)
for c in all_classes:
new_c = find_class_long_name(c)
if new_c:
print '%s ---> %s' % (c, new_c)
code=re.sub(r'\b%s\b' %c,new_c,code)
else:
print 'skipped:',c
# write code to new file
update 2: I think I can just replace the module import lines without changing the code
def find_module(c):
for k,v in mappings.iteritems():
if c in v:
return k
else:
return None
with open(bad_file) as f:
code = f.read()
# print code
all_classes = re.findall(r'\bQ[A-Z]\w*\b', code)
all_classes=set(all_classes)
for c in all_classes:
c_module = find_module(c)
if c_module:
cache[c_module].append(c)
else:
print 'skipped:',c
cmd = ''
for k,v in cache.iteritems():
if cache[k]:
cmd+='from %s import (%s)' % (k, ', '.join(sorted(cache[k])))
cmd+='\n'
print 'new import:\n'
print cmd
from x import *are we talking about?QtGui.orQtCore.as a prefixpylintonce you replace everything to get a list of import errors and then add it tofrom x import y, z?