From a2ca22c0eb15bd465a62708cd47fd5c79eb589e2 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 8 May 2019 13:15:18 -0600 Subject: [PATCH 1/5] bpo-29779: New environment variable PYTHONHISTORY It can be used to set the location of a .python_history file. Co-Authored-By: Levi Sabah <0xl3vi@gmail.com> --- Doc/using/cmdline.rst | 7 +++++++ Doc/whatsnew/3.8.rst | 3 +++ Lib/site.py | 21 ++++++++++++------- Lib/test/test_site.py | 5 +++++ .../2019-05-08-13-14-11.bpo-29779.jg33dp.rst | 2 ++ Misc/python.man | 3 +++ Python/coreconfig.c | 3 ++- 7 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-08-13-14-11.bpo-29779.jg33dp.rst diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index fd47ce2ab53849..6e52fecb9f35ee 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -918,6 +918,13 @@ conflict. .. versionadded:: 3.7 See :pep:`540` for more details. +.. envvar:: PYTHONHISTORY + + This environment variable can be used to set the location of a + ``.python_history`` file (it is ``~/.python_history`` by default). + + .. versionadded:: 3.8 + Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index d6388f8faaba4f..faa7e5804dea85 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -206,6 +206,9 @@ Other Language Changes and Windows use this to properly terminate scripts in interactive sessions. (Contributed by Google via Gregory P. Smith in :issue:`1054041`.) +* The new :envvar:`PYTHONHISTORY` environment variable can be used to change + the location of a ``.python_history`` file. + (Contributed by Levi Sabah and Zackery Spytz in :issue:`29779`.) New Modules =========== diff --git a/Lib/site.py b/Lib/site.py index ad1146332b0ab7..80f44129d71f7c 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -393,6 +393,17 @@ def setcopyright(): def sethelper(): builtins.help = _sitebuiltins._Helper() +def gethistoryfile(): + """Check if the PYTHONHISTORY environment variable is set and define + it as the .python_history file. If PYTHONHISTORY is not set, use the + default ~/.python_history file. + """ + h = os.environ.get("PYTHONHISTORY") + if h: + return h + return os.path.join(os.path.expanduser('~'), + '.python_history') + def enablerlcompleter(): """Enable default readline configuration on interactive prompts, by registering a sys.__interactivehook__. @@ -428,13 +439,9 @@ def register_readline(): pass if readline.get_current_history_length() == 0: - # If no history was loaded, default to .python_history. - # The guard is necessary to avoid doubling history size at - # each interpreter exit when readline was already configured - # through a PYTHONSTARTUP hook, see: - # http://bugs.python.org/issue5845#msg198636 - history = os.path.join(os.path.expanduser('~'), - '.python_history') + # If no history was loaded, default to .python_history, + # or PYTHONHISTORY. + history = gethistoryfile() try: readline.read_history_file(history) except OSError: diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 41c4229919507b..4eb9d212fcddc7 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -311,6 +311,11 @@ def test_no_home_directory(self): mock_addsitedir.assert_not_called() self.assertFalse(known_paths) + def test_gethistoryfile(self): + with EnvironmentVarGuard() as environ: + environ['PYTHONHISTORY'] = 'xoxo' + self.assertEqual(site.gethistoryfile(), "xoxo") + class PthFile(object): """Helper class for handling testing of .pth files""" diff --git a/Misc/NEWS.d/next/Library/2019-05-08-13-14-11.bpo-29779.jg33dp.rst b/Misc/NEWS.d/next/Library/2019-05-08-13-14-11.bpo-29779.jg33dp.rst new file mode 100644 index 00000000000000..32d5efc990699e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-08-13-14-11.bpo-29779.jg33dp.rst @@ -0,0 +1,2 @@ +Add a new :envvar:`PYTHONHISTORY` environment variable to set the location +of a ``.python_history`` file. diff --git a/Misc/python.man b/Misc/python.man index 8d5ad8cd6ca87f..e03ddb35e040a8 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -502,6 +502,9 @@ show how long each import takes. This is exactly equivalent to setting .IP PYTHONBREAKPOINT If this environment variable is set to 0, it disables the default debugger. It can be set to the callable of your debugger of choice. +.IP PYTHONHISTORY +This environment variable can be used to set the location of a history file +(it is \fI~/.python_history\fP by default). .SS Debug-mode variables Setting these variables only has an effect in a debug build of Python, that is, if Python was configured with the diff --git a/Python/coreconfig.c b/Python/coreconfig.c index ac01712127ac0a..cd250178023430 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -95,7 +95,8 @@ static const char usage_6[] = "PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n" " debugger. It can be set to the callable of your debugger of choice.\n" "PYTHONDEVMODE: enable the development mode.\n" -"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n"; +"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n" +"PYTHONHISTORY: the location of a .python_history file.\n"; #if defined(MS_WINDOWS) # define PYTHONHOMEHELP "\\python{major}{minor}" From d13fd90278da3ef70d35270f7dab7ca208287c91 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Tue, 14 May 2019 05:21:59 -0600 Subject: [PATCH 2/5] Address the review comments. --- Doc/using/cmdline.rst | 3 ++- Lib/site.py | 8 ++++---- Misc/python.man | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 6e52fecb9f35ee..50bf6f2d302fe3 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -921,7 +921,8 @@ conflict. .. envvar:: PYTHONHISTORY This environment variable can be used to set the location of a - ``.python_history`` file (it is ``~/.python_history`` by default). + ``.python_history`` file (by default, it is ``.python_history`` in the + user's home directory). .. versionadded:: 3.8 diff --git a/Lib/site.py b/Lib/site.py index 80f44129d71f7c..246c59b0fa357d 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -396,11 +396,11 @@ def sethelper(): def gethistoryfile(): """Check if the PYTHONHISTORY environment variable is set and define it as the .python_history file. If PYTHONHISTORY is not set, use the - default ~/.python_history file. + default .python_history file. """ - h = os.environ.get("PYTHONHISTORY") - if h: - return h + history = os.environ.get("PYTHONHISTORY") + if history: + return history return os.path.join(os.path.expanduser('~'), '.python_history') diff --git a/Misc/python.man b/Misc/python.man index e03ddb35e040a8..8a579bca0aec00 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -504,7 +504,7 @@ If this environment variable is set to 0, it disables the default debugger. It can be set to the callable of your debugger of choice. .IP PYTHONHISTORY This environment variable can be used to set the location of a history file -(it is \fI~/.python_history\fP by default). +(on UNIX, it is \fI~/.python_history\fP by default). .SS Debug-mode variables Setting these variables only has an effect in a debug build of Python, that is, if Python was configured with the From 9b7398ccf4c67b022c1a9392ced3f233ae01d567 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 15 May 2019 18:09:43 -0600 Subject: [PATCH 3/5] Account for sys.flags.ignore_environment. --- Lib/site.py | 11 ++++++++--- Lib/test/test_site.py | 7 +++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Lib/site.py b/Lib/site.py index 246c59b0fa357d..e5d08d66c05ca2 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -398,9 +398,10 @@ def gethistoryfile(): it as the .python_history file. If PYTHONHISTORY is not set, use the default .python_history file. """ - history = os.environ.get("PYTHONHISTORY") - if history: - return history + if not sys.flags.ignore_environment: + history = os.environ.get("PYTHONHISTORY") + if history: + return history return os.path.join(os.path.expanduser('~'), '.python_history') @@ -441,6 +442,10 @@ def register_readline(): if readline.get_current_history_length() == 0: # If no history was loaded, default to .python_history, # or PYTHONHISTORY. + # The guard is necessary to avoid doubling history size at + # each interpreter exit when readline was already configured + # through a PYTHONSTARTUP hook, see: + # http://bugs.python.org/issue5845#msg198636 history = gethistoryfile() try: readline.read_history_file(history) diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 4eb9d212fcddc7..c35414d7559004 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -9,6 +9,7 @@ from test import support from test.support import (captured_stderr, TESTFN, EnvironmentVarGuard, change_cwd) +from test.support.script_helper import assert_python_ok import builtins import os import sys @@ -316,6 +317,12 @@ def test_gethistoryfile(self): environ['PYTHONHISTORY'] = 'xoxo' self.assertEqual(site.gethistoryfile(), "xoxo") + # Check that PYTHONHISTORY is ignored in isolated mode. + rc, out, err = assert_python_ok('-I', '-c', + 'import site; assert site.gethistoryfile() != "file"', + PYTHONHISTORY='file') + self.assertEqual(rc, 0) + class PthFile(object): """Helper class for handling testing of .pth files""" From fe6c760026350ff6ba7eb89a7f42cd35b4422cb9 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 15 May 2019 19:09:03 -0600 Subject: [PATCH 4/5] Fix Travis. --- Lib/test/test_site.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index c35414d7559004..a5a7ddcbd0a69d 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -313,14 +313,16 @@ def test_no_home_directory(self): self.assertFalse(known_paths) def test_gethistoryfile(self): - with EnvironmentVarGuard() as environ: - environ['PYTHONHISTORY'] = 'xoxo' - self.assertEqual(site.gethistoryfile(), "xoxo") + filename = 'file' + rc, out, err = assert_python_ok('-c', + f'import site; assert site.gethistoryfile() == "{filename}"', + PYTHONHISTORY=filename) + self.assertEqual(rc, 0) # Check that PYTHONHISTORY is ignored in isolated mode. rc, out, err = assert_python_ok('-I', '-c', - 'import site; assert site.gethistoryfile() != "file"', - PYTHONHISTORY='file') + f'import site; assert site.gethistoryfile() != "{filename}"', + PYTHONHISTORY=filename) self.assertEqual(rc, 0) From bc5b7714f194299fe314d4228890d214b5737489 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 4 Jan 2024 14:32:41 +0200 Subject: [PATCH 5/5] Rename to PYTHON_HISTORY and target 3.13 --- Doc/using/cmdline.rst | 16 ++++++++-------- Doc/whatsnew/3.13.rst | 5 +++++ Doc/whatsnew/3.8.rst | 4 ---- Lib/site.py | 10 ++++++---- Lib/test/test_site.py | 6 +++--- .../2019-05-08-13-14-11.bpo-29779.jg33dp.rst | 2 +- Misc/python.man | 6 +++--- Python/initconfig.c | 2 +- 8 files changed, 27 insertions(+), 24 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 485f8b41579344..0804e6a7580ad1 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -1077,14 +1077,6 @@ conflict. .. versionadded:: 3.7 -.. envvar:: PYTHONHISTORY - - This environment variable can be used to set the location of a - ``.python_history`` file (by default, it is ``.python_history`` in the - user's home directory). - - .. versionadded:: 3.8 - .. envvar:: PYTHONWARNDEFAULTENCODING If this environment variable is set to a non-empty string, issue a @@ -1147,6 +1139,14 @@ conflict. .. versionadded:: 3.13 +.. envvar:: PYTHON_HISTORY + + This environment variable can be used to set the location of a + ``.python_history`` file (by default, it is ``.python_history`` in the + user's home directory). + + .. versionadded:: 3.13 + Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 3ab6d1ddc6ef21..59b9281e6d2b89 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -132,6 +132,11 @@ Other Language Changes equivalent of the :option:`-X frozen_modules <-X>` command-line option. (Contributed by Yilei Yang in :gh:`111374`.) +* The new :envvar:`PYTHON_HISTORY` environment variable can be used to change + the location of a ``.python_history`` file. + (Contributed by Levi Sabah, Zackery Spytz and Hugo van Kemenade in + :gh:`73965`.) + New Modules =========== diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 0a3d407edd3f39..d373fa163ff737 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -539,10 +539,6 @@ Other Language Changes :meth:`~__setstate__` method. (Contributed by Pierre Glaser and Olivier Grisel in :issue:`35900`.) -* The new :envvar:`PYTHONHISTORY` environment variable can be used to change - the location of a ``.python_history`` file. - (Contributed by Levi Sabah and Zackery Spytz in :issue:`29779`.) - New Modules =========== diff --git a/Lib/site.py b/Lib/site.py index 2a05ccb647448c..eea92dfc194333 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -433,18 +433,20 @@ def setcopyright(): def sethelper(): builtins.help = _sitebuiltins._Helper() + def gethistoryfile(): - """Check if the PYTHONHISTORY environment variable is set and define - it as the .python_history file. If PYTHONHISTORY is not set, use the + """Check if the PYTHON_HISTORY environment variable is set and define + it as the .python_history file. If PYTHON_HISTORY is not set, use the default .python_history file. """ if not sys.flags.ignore_environment: - history = os.environ.get("PYTHONHISTORY") + history = os.environ.get("PYTHON_HISTORY") if history: return history return os.path.join(os.path.expanduser('~'), '.python_history') + def enablerlcompleter(): """Enable default readline configuration on interactive prompts, by registering a sys.__interactivehook__. @@ -480,7 +482,7 @@ def register_readline(): if readline.get_current_history_length() == 0: # If no history was loaded, default to .python_history, - # or PYTHONHISTORY. + # or PYTHON_HISTORY. # The guard is necessary to avoid doubling history size at # each interpreter exit when readline was already configured # through a PYTHONSTARTUP hook, see: diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 08056095241268..e26b48ee9483d5 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -343,13 +343,13 @@ def test_gethistoryfile(self): filename = 'file' rc, out, err = assert_python_ok('-c', f'import site; assert site.gethistoryfile() == "{filename}"', - PYTHONHISTORY=filename) + PYTHON_HISTORY=filename) self.assertEqual(rc, 0) - # Check that PYTHONHISTORY is ignored in isolated mode. + # Check that PYTHON_HISTORY is ignored in isolated mode. rc, out, err = assert_python_ok('-I', '-c', f'import site; assert site.gethistoryfile() != "{filename}"', - PYTHONHISTORY=filename) + PYTHON_HISTORY=filename) self.assertEqual(rc, 0) def test_trace(self): diff --git a/Misc/NEWS.d/next/Library/2019-05-08-13-14-11.bpo-29779.jg33dp.rst b/Misc/NEWS.d/next/Library/2019-05-08-13-14-11.bpo-29779.jg33dp.rst index 32d5efc990699e..49d0ba98c4a641 100644 --- a/Misc/NEWS.d/next/Library/2019-05-08-13-14-11.bpo-29779.jg33dp.rst +++ b/Misc/NEWS.d/next/Library/2019-05-08-13-14-11.bpo-29779.jg33dp.rst @@ -1,2 +1,2 @@ -Add a new :envvar:`PYTHONHISTORY` environment variable to set the location +Add a new :envvar:`PYTHON_HISTORY` environment variable to set the location of a ``.python_history`` file. diff --git a/Misc/python.man b/Misc/python.man index 414ab62f202f99..0f5dfa2e2289f7 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -601,12 +601,12 @@ show how long each import takes. This is exactly equivalent to setting .IP PYTHONBREAKPOINT If this environment variable is set to 0, it disables the default debugger. It can be set to the callable of your debugger of choice. -.IP PYTHONHISTORY -This environment variable can be used to set the location of a history file -(on UNIX, it is \fI~/.python_history\fP by default). .IP PYTHON_COLORS If this variable is set to 1, the interpreter will colorize various kinds of output. Setting it to 0 deactivates this behavior. +.IP PYTHON_HISTORY +This environment variable can be used to set the location of a history file +(on Unix, it is \fI~/.python_history\fP by default). .SS Debug-mode variables Setting these variables only has an effect in a debug build of Python, that is, if Python was configured with the diff --git a/Python/initconfig.c b/Python/initconfig.c index 47c5b24ca57c6e..aad3b3d53ca787 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -284,7 +284,6 @@ static const char usage_envvars[] = " os.cpu_count(), and multiprocessing.cpu_count() if set to a positive integer.\n" "PYTHONDEVMODE: enable the development mode.\n" "PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n" -"PYTHONHISTORY: the location of a .python_history file.\n" "PYTHONWARNDEFAULTENCODING: enable opt-in EncodingWarning for 'encoding=None'.\n" "PYTHONNODEBUGRANGES: if this variable is set, it disables the inclusion of the \n" " tables mapping extra location information (end line, start column offset \n" @@ -297,6 +296,7 @@ static const char usage_envvars[] = "PYTHON_COLORS : If this variable is set to 1, the interpreter will" " colorize various kinds of output. Setting it to 0 deactivates this behavior.\n" "These variables have equivalent command-line parameters (see --help for details):\n" +"PYTHON_HISTORY: the location of a .python_history file.\n" "PYTHONDEBUG : enable parser debug mode (-d)\n" "PYTHONDONTWRITEBYTECODE : don't write .pyc files (-B)\n" "PYTHONINSPECT : inspect interactively after running script (-i)\n"