Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Prev Previous commit
Next Next commit
Add test, refine docs, add whatsnew, separate run_presite in pylifecy…
…cle.c
  • Loading branch information
ambv committed Oct 13, 2023
commit b89548d9e5f55331dde9c0a9a844a235d734373f
18 changes: 11 additions & 7 deletions Doc/using/cmdline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,10 @@ Miscellaneous options
container system. See also :envvar:`PYTHON_CPU_COUNT`.
If *n* is ``default``, nothing is overridden.
* :samp:`-X presite={package.module}` specifies a module that should be
imported before ``site.py`` is executed. Python needs to be
:ref:`built in debug mode <debug-build>` for this option to exist.
See also :envvar:`PYTHON_PRESITE <PYTHON_PRESITE=package.module>`.
imported before ``site.py`` is executed and before the :mod:`__main__`
module exists. Therefore, the imported module isn't :mod:`__main__`.
Python needs to be :ref:`built in debug mode <debug-build>` for this
option to exist. See also :envvar:`PYTHON_PRESITE`.

It also allows passing arbitrary values and retrieving them through the
:data:`sys._xoptions` dictionary.
Expand Down Expand Up @@ -1099,19 +1100,22 @@ Debug-mode variables

Need Python configured with the :option:`--with-trace-refs` build option.

.. envvar:: PYTHONDUMPREFSFILE=FILENAME
.. envvar:: PYTHONDUMPREFSFILE

If set, Python will dump objects and reference counts still alive
after shutting down the interpreter into a file called *FILENAME*.
after shutting down the interpreter into a file under the path given
as the value to this environment variable.

Need Python configured with the :option:`--with-trace-refs` build option.

.. versionadded:: 3.11

.. envvar:: PYTHON_PRESITE=package.module
.. envvar:: PYTHON_PRESITE
Comment thread
ambv marked this conversation as resolved.

If this variable is set to a module, that module will be imported
early in the interpreter lifecycle, before ``site.py`` is executed.
early in the interpreter lifecycle, before ``site.py`` is executed,
Comment thread
ambv marked this conversation as resolved.
Outdated
and before the :mod:`__main__` module is created. Therefore, the
imported module is not treated as :mod:`__main__`.

See also the :option:`-X presite <-X>` command-line option,
which takes precedence over this variable.
Expand Down
10 changes: 10 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1348,3 +1348,13 @@ removed, although there is currently no date scheduled for their removal.

* Remove undocumented ``PY_TIMEOUT_MAX`` constant from the limited C API.
(Contributed by Victor Stinner in :gh:`110014`.)


Regression Test Changes
=======================

* Python built with :file:`configure` :option:`--with-pydebug` now
supports a :option:`-X presite=package.module <-X>` command-line
option. If used, it specifies a module that should be imported early
in the lifecycle of the interpreter, before ``site.py`` is executed.
(Contributed by Łukasz Langa in :gh:`110769`.)
16 changes: 16 additions & 0 deletions Lib/test/test_embed.py
Original file line number Diff line number Diff line change
Expand Up @@ -1820,6 +1820,22 @@ def test_no_memleak(self):
self.assertEqual(refs, 0, out)
self.assertEqual(blocks, 0, out)

@unittest.skipUnless(support.Py_DEBUG,
'-X presite requires a Python debug build')
def test_presite(self):
cmd = [sys.executable, "-I", "-X", "presite=test.reperf", "-c", "print('cmd')"]
proc = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
)
self.assertEqual(proc.returncode, 0)
out = proc.stdout.strip()
self.assertIn("10 times sub", out)
self.assertIn("CPU seconds", out)
self.assertIn("cmd", out)


class StdPrinterTests(EmbeddingTestsMixin, unittest.TestCase):
# Test PyStdPrinter_Type which is used by _PySys_SetPreliminaryStderr():
Expand Down
48 changes: 29 additions & 19 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,34 @@ pyinit_main_reconfigure(PyThreadState *tstate)
}


static void
run_presite(PyThreadState *tstate)
{
PyInterpreterState *interp = tstate->interp;
const PyConfig *config = _PyInterpreterState_GetConfig(interp);

if (config->run_presite) {
PyObject *presite_modname = PyUnicode_FromWideChar(
config->run_presite,
wcslen(config->run_presite)
);
if (presite_modname == NULL) {
fprintf(stderr, "Could not convert pre-site module name to unicode\n");
Py_DECREF(presite_modname);
}
else {
PyObject *presite = PyImport_Import(presite_modname);
if (presite == NULL) {
fprintf(stderr, "pre-site import failed:\n");
_PyErr_Print(tstate);
}
Py_XDECREF(presite);
Py_DECREF(presite_modname);
}
}
Comment thread
ambv marked this conversation as resolved.
}


static PyStatus
init_interp_main(PyThreadState *tstate)
{
Expand Down Expand Up @@ -1158,25 +1186,7 @@ init_interp_main(PyThreadState *tstate)
}

#ifdef Py_DEBUG
if (config->run_presite) {
PyObject *presite_modname = PyUnicode_FromWideChar(
config->run_presite,
wcslen(config->run_presite)
);
if (presite_modname == NULL) {
fprintf(stderr, "Could not convert module name to unicode\n");
Py_DECREF(presite_modname);
}
else {
PyObject *presite = PyImport_Import(presite_modname);
if (presite == NULL) {
fprintf(stderr, "pre-site import failed:\n");
_PyErr_Print(tstate);
}
Py_XDECREF(presite);
Py_DECREF(presite_modname);
}
}
run_presite(tstate);
#endif

status = add_main_module(interp);
Expand Down