Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7aff2de

Browse files
authored
pythongh-120057: Add os.environ.refresh() method (python#120059)
1 parent56c3815 commit7aff2de

File tree

7 files changed

+124
-4
lines changed

7 files changed

+124
-4
lines changed

‎Doc/library/os.rst‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ process and user.
193193
to the environment made after this time are not reflected in:data:`os.environ`,
194194
except for changes made by modifying:data:`os.environ` directly.
195195

196+
The:meth:`!os.environ.refresh()` method updates:data:`os.environ` with
197+
changes to the environment made by:func:`os.putenv`, by
198+
:func:`os.unsetenv`, or made outside Python in the same process.
199+
196200
This mapping may be used to modify the environment as well as query the
197201
environment.:func:`putenv` will be called automatically when the mapping
198202
is modified.
@@ -225,6 +229,9 @@ process and user.
225229
..versionchanged::3.9
226230
Updated to support:pep:`584`'s merge (``|``) and update (``|=``) operators.
227231

232+
..versionchanged::3.14
233+
Added the:meth:`!os.environ.refresh()` method.
234+
228235

229236
..data::environb
230237

@@ -561,6 +568,8 @@ process and user.
561568
of:data:`os.environ`. This also applies to:func:`getenv` and:func:`getenvb`, which
562569
respectively use:data:`os.environ` and:data:`os.environb` in their implementations.
563570

571+
See also the:data:`os.environ.refresh() <os.environ>` method.
572+
564573
..note::
565574

566575
On some platforms, including FreeBSD and macOS, setting ``environ`` may
@@ -809,6 +818,8 @@ process and user.
809818
don't update:data:`os.environ`, so it is actually preferable to delete items of
810819
:data:`os.environ`.
811820

821+
See also the:data:`os.environ.refresh() <os.environ>` method.
822+
812823
..audit-event::os.unsetenv key os.unsetenv
813824

814825
..versionchanged::3.9

‎Doc/whatsnew/3.14.rst‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ ast
9292
Added:func:`ast.compare` for comparing two ASTs.
9393
(Contributed by Batuhan Taskaya and Jeremy Hylton in:issue:`15987`.)
9494

95+
os
96+
--
97+
98+
* Added the:data:`os.environ.refresh() <os.environ>` method to update
99+
:data:`os.environ` with changes to the environment made by:func:`os.putenv`,
100+
by:func:`os.unsetenv`, or made outside Python in the same process.
101+
(Contributed by Victor Stinner in:gh:`120057`.)
95102

96103

97104
Optimizations

‎Lib/os.py‎

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ def _get_exports_list(module):
6464
fromposiximport_have_functions
6565
exceptImportError:
6666
pass
67+
try:
68+
fromposiximport_create_environ
69+
exceptImportError:
70+
pass
6771

6872
importposix
6973
__all__.extend(_get_exports_list(posix))
@@ -88,6 +92,10 @@ def _get_exports_list(module):
8892
fromntimport_have_functions
8993
exceptImportError:
9094
pass
95+
try:
96+
fromntimport_create_environ
97+
exceptImportError:
98+
pass
9199

92100
else:
93101
raiseImportError('no os specific module found')
@@ -773,7 +781,18 @@ def __ror__(self, other):
773781
new.update(self)
774782
returnnew
775783

776-
def_createenviron():
784+
if_exists("_create_environ"):
785+
defrefresh(self):
786+
data=_create_environ()
787+
ifname=='nt':
788+
data= {self.encodekey(key):value
789+
forkey,valueindata.items()}
790+
791+
# modify in-place to keep os.environb in sync
792+
self._data.clear()
793+
self._data.update(data)
794+
795+
def_create_environ_mapping():
777796
ifname=='nt':
778797
# Where Env Var Names Must Be UPPERCASE
779798
defcheck_str(value):
@@ -803,8 +822,8 @@ def decode(value):
803822
encode,decode)
804823

805824
# unicode environ
806-
environ=_createenviron()
807-
del_createenviron
825+
environ=_create_environ_mapping()
826+
del_create_environ_mapping
808827

809828

810829
defgetenv(key,default=None):

‎Lib/test/test_os.py‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,52 @@ def test_ror_operator(self):
12981298
self._test_underlying_process_env('_A_','')
12991299
self._test_underlying_process_env(overridden_key,original_value)
13001300

1301+
deftest_refresh(self):
1302+
# Test os.environ.refresh()
1303+
has_environb=hasattr(os,'environb')
1304+
1305+
# Test with putenv() which doesn't update os.environ
1306+
os.environ['test_env']='python_value'
1307+
os.putenv("test_env","new_value")
1308+
self.assertEqual(os.environ['test_env'],'python_value')
1309+
ifhas_environb:
1310+
self.assertEqual(os.environb[b'test_env'],b'python_value')
1311+
1312+
os.environ.refresh()
1313+
self.assertEqual(os.environ['test_env'],'new_value')
1314+
ifhas_environb:
1315+
self.assertEqual(os.environb[b'test_env'],b'new_value')
1316+
1317+
# Test with unsetenv() which doesn't update os.environ
1318+
os.unsetenv('test_env')
1319+
self.assertEqual(os.environ['test_env'],'new_value')
1320+
ifhas_environb:
1321+
self.assertEqual(os.environb[b'test_env'],b'new_value')
1322+
1323+
os.environ.refresh()
1324+
self.assertNotIn('test_env',os.environ)
1325+
ifhas_environb:
1326+
self.assertNotIn(b'test_env',os.environb)
1327+
1328+
ifhas_environb:
1329+
# test os.environb.refresh() with putenv()
1330+
os.environb[b'test_env']=b'python_value2'
1331+
os.putenv("test_env","new_value2")
1332+
self.assertEqual(os.environb[b'test_env'],b'python_value2')
1333+
self.assertEqual(os.environ['test_env'],'python_value2')
1334+
1335+
os.environb.refresh()
1336+
self.assertEqual(os.environb[b'test_env'],b'new_value2')
1337+
self.assertEqual(os.environ['test_env'],'new_value2')
1338+
1339+
# test os.environb.refresh() with unsetenv()
1340+
os.unsetenv('test_env')
1341+
self.assertEqual(os.environb[b'test_env'],b'new_value2')
1342+
self.assertEqual(os.environ['test_env'],'new_value2')
1343+
1344+
os.environb.refresh()
1345+
self.assertNotIn(b'test_env',os.environb)
1346+
self.assertNotIn('test_env',os.environ)
13011347

13021348
classWalkTests(unittest.TestCase):
13031349
"""Tests for os.walk()."""
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Added the:data:`os.environ.refresh() <os.environ>` method to update
2+
:data:`os.environ` with changes to the environment made by:func:`os.putenv`,
3+
by:func:`os.unsetenv`, or made outside Python in the same process.
4+
Patch by Victor Stinner.

‎Modules/clinic/posixmodule.c.h‎

Lines changed: 19 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎Modules/posixmodule.c‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16809,6 +16809,20 @@ os__is_inputhook_installed_impl(PyObject *module)
1680916809
returnPyBool_FromLong(PyOS_InputHook!=NULL);
1681016810
}
1681116811

16812+
/*[clinic input]
16813+
os._create_environ
16814+
16815+
Create the environment dictionary.
16816+
[clinic start generated code]*/
16817+
16818+
staticPyObject*
16819+
os__create_environ_impl(PyObject*module)
16820+
/*[clinic end generated code: output=19d9039ab14f8ad4 input=a4c05686b34635e8]*/
16821+
{
16822+
returnconvertenviron();
16823+
}
16824+
16825+
1681216826
staticPyMethodDefposix_methods[]= {
1681316827

1681416828
OS_STAT_METHODDEF
@@ -17023,6 +17037,7 @@ static PyMethodDef posix_methods[] = {
1702317037
OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF
1702417038
OS__INPUTHOOK_METHODDEF
1702517039
OS__IS_INPUTHOOK_INSTALLED_METHODDEF
17040+
OS__CREATE_ENVIRON_METHODDEF
1702617041
{NULL,NULL}/* Sentinel */
1702717042
};
1702817043

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp