添加清理 pycache 和编译扩展的功能
This commit is contained in:
@@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def clean_pycache(root_dir):
|
||||||
|
"""
|
||||||
|
Recursively deletes all __pycache__ directories and .pyc files.
|
||||||
|
"""
|
||||||
|
print(f"Cleaning __pycache__ in: {root_dir}")
|
||||||
|
for root, dirs, files in os.walk(root_dir):
|
||||||
|
# Delete __pycache__ directories
|
||||||
|
if "__pycache__" in dirs:
|
||||||
|
pycache_path = os.path.join(root, "__pycache__")
|
||||||
|
print(f"Removing directory: {pycache_path}")
|
||||||
|
shutil.rmtree(pycache_path)
|
||||||
|
dirs.remove("__pycache__") # Don't visit the deleted directory
|
||||||
|
|
||||||
|
# Delete orphan .pyc files
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".pyc"):
|
||||||
|
pyc_path = os.path.join(root, file)
|
||||||
|
print(f"Removing file: {pyc_path}")
|
||||||
|
os.remove(pyc_path)
|
||||||
|
|
||||||
|
def clean_extensions(root_dir):
|
||||||
|
"""
|
||||||
|
Recursively deletes all compiled .so and .pyd files.
|
||||||
|
"""
|
||||||
|
print(f"Cleaning compiled extensions in: {root_dir}")
|
||||||
|
for root, dirs, files in os.walk(root_dir):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".so") or file.endswith(".pyd"):
|
||||||
|
ext_path = os.path.join(root, file)
|
||||||
|
print(f"Removing extension: {ext_path}")
|
||||||
|
os.remove(ext_path)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||||
|
|
||||||
|
# Clean pycache
|
||||||
|
clean_pycache(project_root)
|
||||||
|
|
||||||
|
# Optionally clean extensions if requested via argument
|
||||||
|
if len(sys.argv) > 1 and sys.argv[1] == "--all":
|
||||||
|
clean_extensions(project_root)
|
||||||
|
|
||||||
|
print("Cleanup complete.")
|
||||||
+96
-1
@@ -6,6 +6,83 @@ from setuptools import setup, Extension
|
|||||||
from Cython.Build import cythonize
|
from Cython.Build import cythonize
|
||||||
|
|
||||||
|
|
||||||
|
def delete_source_files(target_dirs):
|
||||||
|
"""
|
||||||
|
Deletes the original .py files in the target directories after successful compilation.
|
||||||
|
Caution: This will remove your source code!
|
||||||
|
"""
|
||||||
|
if isinstance(target_dirs, str):
|
||||||
|
target_dirs = [target_dirs]
|
||||||
|
|
||||||
|
project_root = os.getcwd()
|
||||||
|
print(f"Deleting source .py files in: {target_dirs}")
|
||||||
|
|
||||||
|
for target_dir in target_dirs:
|
||||||
|
if not os.path.exists(target_dir):
|
||||||
|
continue
|
||||||
|
|
||||||
|
abs_target_path = os.path.abspath(target_dir)
|
||||||
|
|
||||||
|
if os.path.isfile(abs_target_path):
|
||||||
|
if abs_target_path.endswith(".py") and os.path.abspath(
|
||||||
|
abs_target_path
|
||||||
|
) != os.path.abspath(__file__):
|
||||||
|
print(f"Deleting source: {abs_target_path}")
|
||||||
|
os.remove(abs_target_path)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# If it's a directory, walk through it
|
||||||
|
for root, dirs, files in os.walk(abs_target_path):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".py"):
|
||||||
|
file_path = os.path.join(root, file)
|
||||||
|
# Skip this script itself
|
||||||
|
if os.path.abspath(file_path) == os.path.abspath(__file__):
|
||||||
|
continue
|
||||||
|
# Skip __init__.py if you want to keep package structure,
|
||||||
|
# but usually Cython can handle them too.
|
||||||
|
print(f"Deleting source: {file_path}")
|
||||||
|
os.remove(file_path)
|
||||||
|
|
||||||
|
|
||||||
|
def clean_extensions(target_dirs):
|
||||||
|
"""
|
||||||
|
Deletes all compiled .so/.pyd files in the target directories.
|
||||||
|
"""
|
||||||
|
if isinstance(target_dirs, str):
|
||||||
|
target_dirs = [target_dirs]
|
||||||
|
|
||||||
|
project_root = os.getcwd()
|
||||||
|
print(f"Cleaning compiled files in: {target_dirs}")
|
||||||
|
|
||||||
|
for target_dir in target_dirs:
|
||||||
|
if not os.path.exists(target_dir):
|
||||||
|
continue
|
||||||
|
|
||||||
|
abs_target_path = os.path.abspath(target_dir)
|
||||||
|
|
||||||
|
if os.path.isfile(abs_target_path):
|
||||||
|
# If it's a .py file, look for its .so/.pyd counterpart
|
||||||
|
dir_name = os.path.dirname(abs_target_path)
|
||||||
|
base_name = os.path.splitext(os.path.basename(abs_target_path))[0]
|
||||||
|
for file in os.listdir(dir_name):
|
||||||
|
if file.startswith(base_name) and (
|
||||||
|
file.endswith(".so") or file.endswith(".pyd")
|
||||||
|
):
|
||||||
|
file_path = os.path.join(dir_name, file)
|
||||||
|
print(f"Removing: {file_path}")
|
||||||
|
os.remove(file_path)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# If it's a directory, walk through it
|
||||||
|
for root, dirs, files in os.walk(abs_target_path):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".so") or file.endswith(".pyd"):
|
||||||
|
file_path = os.path.join(root, file)
|
||||||
|
print(f"Removing: {file_path}")
|
||||||
|
os.remove(file_path)
|
||||||
|
|
||||||
|
|
||||||
def build_extensions(target_dirs):
|
def build_extensions(target_dirs):
|
||||||
"""
|
"""
|
||||||
Compiles all .py files in the target directories (recursively) into .so/.pyd extensions.
|
Compiles all .py files in the target directories (recursively) into .so/.pyd extensions.
|
||||||
@@ -119,17 +196,35 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# Check for help flag
|
# Check for help flag
|
||||||
if len(sys.argv) > 1 and sys.argv[1] in ["--help", "-h"]:
|
if len(sys.argv) > 1 and sys.argv[1] in ["--help", "-h"]:
|
||||||
print("Usage: python scripts/build_extensions.py [directory1] [directory2] ...")
|
print(
|
||||||
|
"Usage: python scripts/build_extensions.py [--clean|--delete-source] [directory1] [directory2] ..."
|
||||||
|
)
|
||||||
print(
|
print(
|
||||||
"Compiles all Python files in the given directories into C extensions (.so/.pyd)."
|
"Compiles all Python files in the given directories into C extensions (.so/.pyd)."
|
||||||
)
|
)
|
||||||
|
print("Use --clean to remove existing compiled extensions.")
|
||||||
|
print("Use --delete-source to remove source .py files after compilation.")
|
||||||
print(f"Default directories if none provided: {DEFAULT_TARGETS}")
|
print(f"Default directories if none provided: {DEFAULT_TARGETS}")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
clean_mode = False
|
||||||
|
delete_source_mode = False
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
|
if sys.argv[1] == "--clean":
|
||||||
|
clean_mode = True
|
||||||
|
target_directories = sys.argv[2:]
|
||||||
|
elif sys.argv[1] == "--delete-source":
|
||||||
|
delete_source_mode = True
|
||||||
|
target_directories = sys.argv[2:]
|
||||||
|
else:
|
||||||
target_directories = sys.argv[1:]
|
target_directories = sys.argv[1:]
|
||||||
else:
|
else:
|
||||||
print(f"No directories specified. Using defaults: {DEFAULT_TARGETS}")
|
print(f"No directories specified. Using defaults: {DEFAULT_TARGETS}")
|
||||||
target_directories = DEFAULT_TARGETS
|
target_directories = DEFAULT_TARGETS
|
||||||
|
|
||||||
|
if clean_mode:
|
||||||
|
clean_extensions(target_directories)
|
||||||
|
elif delete_source_mode:
|
||||||
|
delete_source_files(target_directories)
|
||||||
|
else:
|
||||||
build_extensions(target_directories)
|
build_extensions(target_directories)
|
||||||
|
|||||||
Reference in New Issue
Block a user