fixabsoluteimports.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import os
  2. def walk_directory(root, dirs, files):
  3. for file_path in files:
  4. if 'project_template' not in root and file_path.lower().endswith('.py'):
  5. clean_file(os.path.join(root, file_path))
  6. def clean_file(file_path):
  7. py_source = file(file_path).read()
  8. if 'misago.' in py_source:
  9. package = file_path.rstrip('.py').split('/')
  10. parse_file = True
  11. save_file = False
  12. cursor = 0
  13. while parse_file:
  14. try:
  15. import_start = py_source.index('from ', cursor)
  16. import_end = py_source.index(' import', import_start)
  17. cursor = import_end
  18. import_len = import_end - import_start
  19. import_path = py_source[import_start:import_end].lstrip('from').strip()
  20. if import_path.startswith('misago.'):
  21. cleaned_import = clean_import(package, import_path.split('.'))
  22. if cleaned_import:
  23. save_file = True
  24. cleaned_import_string = 'from {}'.format('.'.join(cleaned_import))
  25. py_source = ''.join((py_source[:import_start], cleaned_import_string, py_source[import_end:]))
  26. cursor -= import_end - import_start - len(cleaned_import_string)
  27. except ValueError:
  28. parse_file = False
  29. if save_file:
  30. with open(file_path, 'w') as package:
  31. print file_path
  32. package.write(py_source)
  33. def clean_import(package, import_path):
  34. if len(package) < 2 or len(import_path) < 2:
  35. # skip non-app import
  36. return
  37. if package[:2] != import_path[:2]:
  38. # skip other app import
  39. return
  40. if package == import_path:
  41. # import from direct child
  42. return ['', '']
  43. if package[:-1] == import_path[:-1]:
  44. # import from sibling module
  45. return ['', import_path[-1]]
  46. if len(package) < len(import_path) and package == import_path[:len(package)]:
  47. # import from child module
  48. return [''] + import_path[len(package):]
  49. if len(package) > len(import_path) and package[:len(import_path)] == import_path:
  50. # import from parent module
  51. return [''] * (len(package) - len(import_path) + 1)
  52. # relative up and down path
  53. relative_path = []
  54. # find upwards path
  55. overlap_len = 2
  56. while True:
  57. if package[:overlap_len + 1] != import_path[:overlap_len + 1]:
  58. break
  59. overlap_len += 1
  60. relative_path += ([''] * (len(package) - overlap_len))[:-1]
  61. # append eventual downwards path
  62. if import_path[overlap_len:]:
  63. relative_path += [''] + import_path[overlap_len:]
  64. return relative_path
  65. if __name__ == '__main__':
  66. for args in os.walk('../misago'):
  67. walk_directory(*args)
  68. print "\nDone! Don't forget to run isort to fix imports ordering!"