3RNN/Lib/site-packages/namex/convert.py
2024-05-26 19:49:15 +02:00

73 lines
3.0 KiB
Python

import os
import shutil
def rewrite_python_file_imports(target_dir, root_name, offset_name, verbose=False):
"""Rewrite internal package imports for move to a `src/` dir structure.
If your project has its code in `package_name/`, and you want to instead
move that code to `package_name/src/`, this script will change all lines
of the form e.g.
`from package_name.x.y import z` to `from package_name.src.x.y import z`
if you call it as
`rewrite_python_file_imports("package_name/", "package_name", "src")`
"""
assert "." not in offset_name
for root, _, files in os.walk(target_dir):
for fname in files:
if fname.endswith(".py"):
fpath = os.path.join(root, fname)
if verbose:
print(f"...processing {fpath}")
with open(fpath) as f:
contents = f.read()
lines = contents.split("\n")
in_string = False
new_lines = []
for line in lines:
if line.strip().startswith('"""') or line.strip().endswith('"""'):
if line.count('"') % 2 == 1:
in_string = not in_string
else:
if not in_string:
# Imports starting from `root_name`.
if line.strip() == f"import {root_name}":
line = line.replace(
f"import {root_name}",
f"import {root_name}.{offset_name} as {root_name}",
)
else:
line = line.replace(
f"import {root_name}.",
f"import {root_name}.{offset_name}.",
)
line = line.replace(
f"from {root_name}.", f"from {root_name}.{offset_name}."
)
line = line.replace(
f"from {root_name} import",
f"from {root_name}.{offset_name} import",
)
new_lines.append(line)
with open(fpath, "w") as f:
f.write("\n".join(new_lines) + "\n")
def convert_codebase(package, code_directory="src"):
if not os.path.exists(package):
raise ValueError(f"No directory named '{package}'.")
os.rename(package, code_directory)
os.mkdir(package)
shutil.move(code_directory, os.path.join(package, code_directory))
rewrite_python_file_imports(
target_dir=package, root_name=package, offset_name="src", verbose=True
)
# Create blank init file at root to make package detectable / importable.
with open(os.path.join(package, "__init__.py"), "w"):
pass