Skip to content

Instantly share code, notes, and snippets.

@dwlehman
Last active October 29, 2015 13:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dwlehman/ab8e159f98d7d9708e4a to your computer and use it in GitHub Desktop.
Save dwlehman/ab8e159f98d7d9708e4a to your computer and use it in GitHub Desktop.
Quick & dirty solution to converting an entire python package/module to use pep8 naming.
# pep8names.py
#
# Convert all python files in a directory to use pep8 naming conventions.
#
# The conversion is done in-place.
#
# Warning: this will also convert names from external packages/modules,
# including the standard library, so you will want to check the
# results.
#
# Author: David Lehman <dlehman@redhat.com>
#
import sys
import re
IGNORE_NAMES = ["getPartitionByPath", "getPartitionBySector",
"getLogicalPartitions", "getExtendedPartition",
"freshDisk", "partitionAlignment", "optimumAlignment",
"minimumAlignment", "getFreeSpacePartitions", "getFreeSpaceRegions",
"primaryPartitionCount", "maxPrimaryPartitionCount",
"maxPartitionLength", "maxPartitionStartSector",
"getLogger", "captureWarnings",
"setUp", "tearDown", "skipUnless", "skipTest"]
CAMEL_CASE_NAME_RE = re.compile(r'_*([a-z]+)([A-Z])')
WORD_DELIM = r'[\s=,()\[\]\{\}.\'"]+'
def convert_name(name):
""" Return the name converted to pep8 style, eg: camelCase->camel_case """
if name not in IGNORE_NAMES and not name.startswith("assert") and \
CAMEL_CASE_NAME_RE.match(name):
converted = re.sub(r'([a-z]+)([A-Z])', '\\1_\\2', name).lower()
else:
converted = name
return converted
def word_indices_from_delim_indices(delim):
""" Return a list of start/end indices of words.
:param list delim: list of list [start, end] for delimiter subtrings
:returns: list of list [start, end] for word substrings
:rtype: list of lists
"""
word_indices = [[0, None]]
for (start, end) in delim:
word_indices[-1][1] = start
word_indices.append([end, None])
return word_indices
def convert_line(line):
""" Return a single line converted to use pep8 names.
:param str line: the line to convert
:returns: the converted line
:rtype: str
The approach seems odd to me, but it works pretty well and does not
require me to parse the code to any meaningful extent. We start by
defining a list of possible delimiters for the names in a line of
python code. You use that to obtain a list of the delimiters in the
line as re match objects. Based on the start and end index of each
delimiter substring, we obtain the start and end index of each name
substring. Then we write each (potentially converted) name out,
separated by the preserved delimiter strings.
"""
converted = ''
if line.lstrip().startswith("class "):
converted = line
else:
delim_indices = [[m.start(), m.end()]
for m in re.finditer(WORD_DELIM, line)]
delims = [line[s:e] for (s, e) in delim_indices]
words = [line[s:e]
for (s, e) in word_indices_from_delim_indices(delim_indices)]
for word, delim in zip(words, delims):
converted += convert_name(word)
converted += delim
return converted
def convert_file(path):
""" Convert a python source file to use pep8 naming.
:param str path: the file's path
:returns: None
:rtype: NoneType
"""
lines = open(path).readlines()
f = open(path, 'w')
for line in lines:
f.write(convert_line(line))
f.close()
if __name__ == "__main__":
import os
import time
warning_text = ("WARNING: this will also convert names from external "
"packages/modules,\n"
" including the standard library, so you will "
"want to check the\n"
" results.")
print(warning_text)
time.sleep(1)
for dirpath, dirnames, filenames in os.walk(sys.argv[1]):
for filename in filenames:
if filename.endswith(".py"):
full_path = dirpath + "/" + filename
print("converting %s..." % full_path)
convert_file(full_path)
print(warning_text)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment