Skip to content

Instantly share code, notes, and snippets.

@dan-oak
Created September 20, 2022 15:15
Show Gist options
  • Save dan-oak/91a13dbec71af5bfc4c263676979eee0 to your computer and use it in GitHub Desktop.
Save dan-oak/91a13dbec71af5bfc4c263676979eee0 to your computer and use it in GitHub Desktop.
amalgamate multiple Python files into a single one
# - imports should only be in the format of "import <module> as <alias>",
# if you do not want an alias, do "import stuff as stuff"
# - imports should only be in the top level scope
import os
import re
curr_dir_path = os.path.dirname(__file__)
main_path = os.path.join(curr_dir_path, "main.py")
delimiter = "\n" + "#" * 80 + "\n"
"""delimiter before and after included module"""
print(f"amalgamating {main_path}")
with open(main_path, "r") as mainf:
main_text = mainf.read()
included_modules_comment_list = []
aliases = set(m for m in re.findall(r'import \w+ as (\w+)', main_text))
amalgamated_modules = {}
def replace(match):
global aliases, included_modules_comment_list
module = match.group(1)
alias = match.group(2) if len(match.groups()) > 1 else module
if module is not None:
try:
with open(os.path.join(curr_dir_path, module + ".py"), "r") as modulef:
if not module in amalgamated_modules:
print(f"including {module, alias}")
included_modules_comment_list += ["# " + module]
return delimiter + f"# inserted module: {module}\n\n" + modulef.read().strip() + delimiter
else:
print(f"skipping {module}: already included")
return f'# skipped module {module}: already included'
except:
pass
print(f"ignoring {module, alias}")
aliases -= {alias}
return f'import {module} as {alias}'
main_text = re.sub(r'import (\w+) as (\w+)', replace, main_text)
for alias in aliases:
main_text = main_text.replace(alias + '.', '')
with open(os.path.join(curr_dir_path, "_build_.py.txt"), "w") as f:
f.write("\n".join(["# amalgamation of:", *included_modules_comment_list, f"# main"]) + "\n\n")
main_text = re.sub(r'#\s*<build-exclude>.*?</build-exclude>',
'# << excluded lines >>',
main_text, flags=re.DOTALL)
f.write(main_text)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment