-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate_init.py
111 lines (82 loc) · 3.28 KB
/
generate_init.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import os
import toml
import argparse
import re
from typing import List, Tuple
from path import Path
def bypyproject(version, project_info):
# Define the content of __init__.py
init_content = f"""\
# Auto-generated __init__.py
# Version of the pyfunc2 package
__version__ = "{version}"
# Import necessary modules and functions here
"""
# Create the __init__.py file in the appropriate directory
#package_dir = os.path.join("src", project_info["name"])
#os.makedirs(package_dir, exist_ok=True)
# with open(os.path.join(package_dir, "__init__.py"), "w") as f:
# f.write(init_content)
#print(f"__init__.py generated at {os.path.join(package_dir, '__init__.py')}")
return init_content
class_function_regex = re.compile(r'(?<!\s )(?:class|def)\s+(?P<name>\w+)')
local_import_regex = re.compile(r'(?<!\s )from \.\w+ import (?P<name>\w+)')
def find_importable_elements_from_files(root: Path) -> List[Tuple[str, str]]:
result = []
for file in root.files('*.py'):
with open(file) as f:
content = f.read()
for match in class_function_regex.finditer(content):
name = match.group('name')
if name is not None:
result.append((file.basename().replace('.py', ''), name))
return result
def find_importable_elements_from_subfolders(root: Path) -> List[Tuple[str, str]]:
result = []
for subdir in root.dirs():
if not (subdir / '__init__.py').exists():
continue
with open(subdir / '__init__.py') as f:
content = f.read()
for match in local_import_regex.finditer(content):
name = match.group('name')
if name is not None:
result.append((subdir.basename(), name))
return result
def get_project_info(path: Path) -> dict:
pyproject_file = path / 'pyproject.toml'
if not pyproject_file.exists():
return {}
with open(pyproject_file) as f:
return toml.load(f)
def get_project_version_by_toml(path="pyproject.toml") -> str:
# Load the pyproject.toml file
with open(path, "r") as f:
pyproject_data = toml.load(f)
# Extract project information
project_info = pyproject_data.get("project", {})
version = project_info.get("version", "0.1.0")
return version
def template_initpy(imports: List[Tuple[str, str]]):
version = 'from ._version import __version__'
template = version
#template = bypyproject(version)
for fname, elname in imports:
template += f'from .{fname} import {elname}\n'
template += '\n# Public API of the package'
template += '\n__all__ = [' + ', '.join([elname for _, elname in imports]) + ']'
return template
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--path', '-p', type=Path, required=False, dest='path', default=None)
args = parser.parse_args()
if args.path is None:
args.path = Path('./').abspath()
imports = find_importable_elements_from_files(args.path) + \
find_importable_elements_from_subfolders(args.path)
print('imports found:', '\n'.join([f'\t{a} - {b}' for a, b in imports]), sep='\n')
init_content = template_initpy(imports)
with open(args.path / '__init__.py', 'w') as f:
f.write(init_content)
if __name__ == "__main__":
main()