6
6
It generates API and formats user and generated APIs.
7
7
"""
8
8
9
- import importlib
10
9
import os
11
10
import re
12
11
import shutil
@@ -24,38 +23,38 @@ def ignore_files(_, filenames):
24
23
def copy_source_to_build_directory (root_path ):
25
24
# Copy sources (`keras/` directory and setup files) to build dir
26
25
build_dir = os .path .join (root_path , BUILD_DIR_NAME )
26
+ build_package_dir = os .path .join (build_dir , PACKAGE )
27
+ build_src_dir = os .path .join (build_package_dir , "src" )
28
+ root_src_dir = os .path .join (root_path , PACKAGE , "src" )
27
29
if os .path .exists (build_dir ):
28
30
shutil .rmtree (build_dir )
29
- os .mkdir (build_dir )
30
- shutil .copytree (
31
- PACKAGE , os .path .join (build_dir , PACKAGE ), ignore = ignore_files
32
- )
31
+ os .makedirs (build_package_dir )
32
+ shutil .copytree (root_src_dir , build_src_dir )
33
33
return build_dir
34
34
35
35
36
36
def create_legacy_directory (package_dir ):
37
37
src_dir = os .path .join (package_dir , "src" )
38
- api_dir = os .path .join (package_dir , "api" )
39
38
# Make keras/_tf_keras/ by copying keras/
40
- tf_keras_dirpath_parent = os .path .join (api_dir , "_tf_keras" )
39
+ tf_keras_dirpath_parent = os .path .join (package_dir , "_tf_keras" )
41
40
tf_keras_dirpath = os .path .join (tf_keras_dirpath_parent , "keras" )
42
41
os .makedirs (tf_keras_dirpath , exist_ok = True )
43
42
with open (os .path .join (tf_keras_dirpath_parent , "__init__.py" ), "w" ) as f :
44
- f .write ("from keras.api. _tf_keras import keras\n " )
45
- with open (os .path .join (api_dir , "__init__.py" )) as f :
43
+ f .write ("from keras._tf_keras import keras\n " )
44
+ with open (os .path .join (package_dir , "__init__.py" )) as f :
46
45
init_file = f .read ()
47
46
init_file = init_file .replace (
48
- "from keras.api import _legacy" ,
49
- "from keras.api import _tf_keras" ,
47
+ "from keras import _legacy as _legacy" ,
48
+ "from keras import _tf_keras as _tf_keras" ,
50
49
)
51
- with open (os .path .join (api_dir , "__init__.py" ), "w" ) as f :
50
+ with open (os .path .join (package_dir , "__init__.py" ), "w" ) as f :
52
51
f .write (init_file )
53
52
# Remove the import of `_tf_keras` in `keras/_tf_keras/keras/__init__.py`
54
- init_file = init_file .replace ("from keras.api import _tf_keras\n " , "\n " )
53
+ init_file = init_file .replace ("from keras import _tf_keras\n " , "\n " )
55
54
with open (os .path .join (tf_keras_dirpath , "__init__.py" ), "w" ) as f :
56
55
f .write (init_file )
57
- for dirname in os .listdir (api_dir ):
58
- dirpath = os .path .join (api_dir , dirname )
56
+ for dirname in os .listdir (package_dir ):
57
+ dirpath = os .path .join (package_dir , dirname )
59
58
if os .path .isdir (dirpath ) and dirname not in (
60
59
"_legacy" ,
61
60
"_tf_keras" ,
@@ -81,7 +80,7 @@ def create_legacy_directory(package_dir):
81
80
for path in os .listdir (os .path .join (src_dir , "legacy" ))
82
81
if os .path .isdir (os .path .join (src_dir , "legacy" , path ))
83
82
]
84
- for root , _ , fnames in os .walk (os .path .join (api_dir , "_legacy" )):
83
+ for root , _ , fnames in os .walk (os .path .join (package_dir , "_legacy" )):
85
84
for fname in fnames :
86
85
if fname .endswith (".py" ):
87
86
legacy_fpath = os .path .join (root , fname )
@@ -95,22 +94,22 @@ def create_legacy_directory(package_dir):
95
94
with open (legacy_fpath ) as f :
96
95
legacy_contents = f .read ()
97
96
legacy_contents = legacy_contents .replace (
98
- "keras.api. _legacy" , "keras.api ._tf_keras.keras"
97
+ "keras._legacy" , "keras._tf_keras.keras"
99
98
)
100
99
if os .path .exists (core_api_fpath ):
101
100
with open (core_api_fpath ) as f :
102
101
core_api_contents = f .read ()
103
102
core_api_contents = core_api_contents .replace (
104
- "from keras.api import _tf_keras\n " , ""
103
+ "from keras import _tf_keras as _tf_keras\n " , ""
105
104
)
106
105
for legacy_submodule in legacy_submodules :
107
106
core_api_contents = core_api_contents .replace (
108
- f"from keras.api import { legacy_submodule } \n " ,
107
+ f"from keras import { legacy_submodule } as { legacy_submodule } \n " , # noqa: E501
109
108
"" ,
110
109
)
111
110
core_api_contents = core_api_contents .replace (
112
- f"keras.api. { legacy_submodule } " ,
113
- f"keras.api. _tf_keras.keras.{ legacy_submodule } " ,
111
+ f"keras.{ legacy_submodule } " ,
112
+ f"keras._tf_keras.keras.{ legacy_submodule } " ,
114
113
)
115
114
# Remove duplicate generated comments string.
116
115
legacy_contents = re .sub (r"\n" , r"\\n" , legacy_contents )
@@ -122,7 +121,7 @@ def create_legacy_directory(package_dir):
122
121
)
123
122
for import_name in legacy_imports :
124
123
core_api_contents = re .sub (
125
- f"\n .* import { import_name } \n " ,
124
+ f"\n .* import { import_name } as { import_name } \n " ,
126
125
r"\n" ,
127
126
core_api_contents ,
128
127
)
@@ -131,68 +130,41 @@ def create_legacy_directory(package_dir):
131
130
f .write (legacy_contents )
132
131
133
132
# Delete keras/api/_legacy/
134
- shutil .rmtree (os .path .join (api_dir , "_legacy" ))
133
+ shutil .rmtree (os .path .join (package_dir , "_legacy" ))
135
134
136
135
137
136
def export_version_string (api_init_fname ):
138
137
with open (api_init_fname ) as f :
139
138
contents = f .read ()
140
139
with open (api_init_fname , "w" ) as f :
141
- contents += "from keras.src.version import __version__\n "
140
+ contents += "from keras.src.version import __version__ as __version__ \n "
142
141
f .write (contents )
143
142
144
143
145
- def update_package_init (template_fname , dest_fname , api_module ):
146
- with open (template_fname ) as template_file :
147
- with open (dest_fname , "w" ) as dest_file :
148
- for line in template_file :
149
- if "# DO NOT EDIT." in line :
150
- dest_file .write (line )
151
- # Import all public symbols from `api/` and `__version__`.
152
- for symbol in api_module .__dict__ .keys ():
153
- if symbol .startswith ("_" ) and symbol != "__version__" :
154
- continue
155
- dest_file .write (f"from keras.api import { symbol } \n " )
156
- # Skip the previous autogenerated block.
157
- for line in template_file :
158
- if "# END DO NOT EDIT." in line :
159
- break
160
- dest_file .write (line )
161
-
162
-
163
144
def build ():
164
- # Backup the `keras/__init__.py` and restore it on error in api gen.
165
145
root_path = os .path .dirname (os .path .abspath (__file__ ))
166
146
code_api_dir = os .path .join (root_path , PACKAGE , "api" )
167
- code_init_fname = os .path .join (root_path , PACKAGE , "__init__.py" )
168
147
# Create temp build dir
169
148
build_dir = copy_source_to_build_directory (root_path )
170
- build_api_dir = os .path .join (build_dir , PACKAGE , "api" )
171
- build_init_fname = os .path .join (build_dir , PACKAGE , "__init__.py " )
149
+ build_api_dir = os .path .join (build_dir , PACKAGE )
150
+ build_src_dir = os .path .join (build_api_dir , "src " )
172
151
build_api_init_fname = os .path .join (build_api_dir , "__init__.py" )
173
152
try :
174
153
os .chdir (build_dir )
175
- # Generates `keras/api` directory.
176
- if os .path .exists (build_api_dir ):
177
- shutil .rmtree (build_api_dir )
178
- if os .path .exists (build_init_fname ):
179
- os .remove (build_init_fname )
180
- os .makedirs (build_api_dir )
181
- namex .generate_api_files (
182
- "keras" , code_directory = "src" , target_directory = "api"
183
- )
154
+ open (build_api_init_fname , "w" ).close ()
155
+ namex .generate_api_files ("keras" , code_directory = "src" )
184
156
# Add __version__ to `api/`.
185
157
export_version_string (build_api_init_fname )
186
158
# Creates `_tf_keras` with full keras API
187
159
create_legacy_directory (package_dir = os .path .join (build_dir , PACKAGE ))
188
- # Update toplevel init with all `api/` imports.
189
- api_module = importlib .import_module (f"{ BUILD_DIR_NAME } .keras.api" )
190
- update_package_init (code_init_fname , build_init_fname , api_module )
191
160
# Copy back the keras/api and keras/__init__.py from build directory
161
+ if os .path .exists (build_src_dir ):
162
+ shutil .rmtree (build_src_dir )
192
163
if os .path .exists (code_api_dir ):
193
164
shutil .rmtree (code_api_dir )
194
- shutil .copytree (build_api_dir , code_api_dir )
195
- shutil .copy (build_init_fname , code_init_fname )
165
+ shutil .copytree (
166
+ build_api_dir , code_api_dir , ignore = shutil .ignore_patterns ("src/" )
167
+ )
196
168
finally :
197
169
# Clean up: remove the build directory (no longer needed)
198
170
shutil .rmtree (build_dir )
0 commit comments