Skip to content

Commit dbfd9c7

Browse files
authored
Merge pull request #126 from Falldog/fix/issue-123-define__file__
feat: add __file__ into entry module
2 parents 1cd7535 + 054e920 commit dbfd9c7

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

src/pyconcrete_exe/pyconcrete_exe.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@
2020

2121

2222
int createAndInitPyconcreteModule();
23-
int execPycContent(PyObject* pyc_content);
23+
int execPycContent(PyObject* pyc_content, const char* filepath);
2424
int runFile(const char* filepath);
25+
PyObject* getFullPath(const char* filepath);
2526

2627

2728
int main(int argc, char *argv[])
@@ -136,7 +137,7 @@ int createAndInitPyconcreteModule()
136137
return ret;
137138
}
138139

139-
int execPycContent(PyObject* pyc_content)
140+
int execPycContent(PyObject* pyc_content, const char* filepath)
140141
{
141142
int ret = RET_OK;
142143
PyObject* py_marshal = NULL;
@@ -169,11 +170,14 @@ int execPycContent(PyObject* pyc_content)
169170
}
170171

171172
// setup global and exec loaded py_code
173+
PyObject* py_full_filepath = getFullPath(filepath);
172174
PyDict_SetItemString(global, "__name__", main_name);
175+
PyDict_SetItemString(global, "__file__", py_full_filepath);
173176
PyDict_SetItemString(global, "__builtins__", PyEval_GetBuiltins());
174177
PyEval_EvalCode(py_code, global, global);
175178

176179
ERROR:
180+
Py_XDECREF(py_full_filepath);
177181
Py_XDECREF(py_code);
178182
Py_XDECREF(global);
179183
Py_XDECREF(pyc_content_wo_magic);
@@ -220,8 +224,23 @@ int runFile(const char* filepath)
220224
}
221225
fclose(src);
222226

223-
ret = execPycContent(py_plaint_content);
227+
ret = execPycContent(py_plaint_content, filepath);
224228

225229
Py_DECREF(py_plaint_content);
226230
return ret;
227231
}
232+
233+
PyObject* getFullPath(const char* filepath)
234+
{
235+
// import os.path
236+
// return os.path.abspath(filepath)
237+
PyObject* path_module = PyImport_ImportModule("os.path");
238+
PyObject* abspath_func = PyObject_GetAttrString(path_module, "abspath");
239+
PyObject* args = Py_BuildValue("(s)", filepath);
240+
PyObject* obj = PyObject_CallObject(abspath_func, args);
241+
242+
Py_XDECREF(path_module);
243+
Py_XDECREF(abspath_func);
244+
Py_XDECREF(args);
245+
return obj;
246+
}

tests/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ def pyconcrete_exe(self):
6262
self._ensure_pyconcrete_exist()
6363
return join(self.bin_dir, exe_name('pyconcrete'))
6464

65-
def pyconcrete(self, *args: [str]):
65+
def pyconcrete(self, *args: [str], cwd=None):
6666
self._ensure_pyconcrete_exist()
67-
return subprocess.check_output([self.pyconcrete_exe, *args]).decode()
67+
return subprocess.check_output([self.pyconcrete_exe, *args], cwd=cwd).decode()
6868

6969
def pyconcrete_cli(self, *args: [str]):
7070
self._ensure_pyconcrete_exist()

tests/test_exe.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
import os.path
1415
import subprocess
1516

1617

@@ -108,3 +109,33 @@ def test_exe__import_pyconcrete__venv_exe__validate__file__(venv_exe, pye_cli, t
108109

109110
# verification
110111
assert pyconcrete__file__ == 'None'
112+
113+
114+
def test_exe__validate_main__file__full_path(venv_exe, pye_cli, tmpdir):
115+
# prepare
116+
pye_path = pye_cli.setup(tmpdir, 'test__file__').source_code("print(__file__)").get_encrypt_path()
117+
118+
# execution
119+
output = venv_exe.pyconcrete(pye_path)
120+
output = output.strip()
121+
pye__file__ = output
122+
123+
# verification
124+
assert pye__file__ == pye_path
125+
126+
127+
def test_exe__validate_main__file__relative_path(venv_exe, pye_cli, tmpdir):
128+
# prepare
129+
# simulate cmd as: `pyconcrete ../foo.pye`
130+
# print(__file__) get correct full path
131+
pye_full_path = pye_cli.setup(tmpdir, 'test__file__').source_code("print(__file__)").get_encrypt_path()
132+
cwd = venv_exe.env_dir
133+
pye_relative_path = os.path.relpath(pye_full_path, cwd)
134+
135+
# execution
136+
output = venv_exe.pyconcrete(pye_relative_path, cwd=cwd)
137+
output = output.strip()
138+
pye__file__ = output
139+
140+
# verification
141+
assert pye__file__ == pye_full_path

0 commit comments

Comments
 (0)