8000 gh-120057: Add os.reload_environ() function (#126268) · python/cpython@4a0d574 · GitHub
[go: up one dir, main page]

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

Appearance settings

Commit 4a0d574

Browse files
vstinnerpicnixzAA-Turner
authored
gh-120057: Add os.reload_environ() function (#126268)
Replace the os.environ.refresh() method with a new os.reload_environ() function. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
1 parent d384050 commit 4a0d574

File tree

5 files changed

+52
-31
lines changed

5 files changed

+52
-31
lines changed

Doc/library/os.rst

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,6 @@ 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-
200196
This mapping may be used to modify the environment as well as query the
201197
environment. :func:`putenv` will be called automatically when the mapping
202198
is modified.
@@ -226,12 +222,13 @@ process and user.
226222
:data:`os.environ`, and when one of the :meth:`pop` or :meth:`clear` methods is
227223
called.
228224

225+
.. seealso::
226+
227+
The :func:`os.reload_environ` function.
228+
229229
.. versionchanged:: 3.9
230230
Updated to support :pep:`584`'s merge (``|``) and update (``|=``) operators.
231231

232-
.. versionchanged:: 3.14
233-
Added the :meth:`!os.environ.refresh` method.
234-
235232

236233
.. data:: environb
237234

@@ -249,6 +246,24 @@ process and user.
249246
Updated to support :pep:`584`'s merge (``|``) and update (``|=``) operators.
250247

251248

249+
.. function:: reload_environ()
250+
251+
The :data:`os.environ` and :data:`os.environb` mappings are a cache of
252+
environment variables at the time that Python started.
253+
As such, changes to the current process environment are not reflected
254+
if made outside Python, or by :func:`os.putenv` or :func:`os.unsetenv`.
255+
Use :func:`!os.reload_environ` to update :data:`os.environ` and :data:`os.environb`
256+
with any such changes to the current process environment.
257+
258+
.. warning::
259+
This function is not thread-safe. Calling it while the environment is
260+
being modified in an other thread is an undefined behavior. Reading from
261+
:data:`os.environ` or :data:`os.environb`, or calling :func:`os.getenv`
262+
while reloading, may return an empty result.
263+
264+
.. versionadded:: next
265+
266+
252267
.. function:: chdir(path)
253268
fchdir(fd)
254269
getcwd()
@@ -568,7 +583,7 @@ process and user.
568583
of :data:`os.environ`. This also applies to :func:`getenv` and :func:`getenvb`, which
569584
respectively use :data:`os.environ` and :data:`os.environb` in their implementations.
570585

571-
See also the :data:`os.environ.refresh() <os.environ>` method.
586+
See also the :func:`os.reload_environ` function.
572587

573588
.. note::
574589

@@ -818,7 +833,7 @@ process and user.
818833
don't update :data:`os.environ`, so it is actually preferable to delete items of
819834
:data:`os.environ`.
820835

821-
See also the :data:`os.environ.refresh() <os.environ>` method.
836+
See also the :func:`os.reload_environ` function.
822837

823838
.. audit-event:: os.unsetenv key os.unsetenv
824839

Doc/whatsnew/3.14.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,10 @@ operator
365365
os
366366
--
367367

368-
* Add the :data:`os.environ.refresh() <os.environ>` method to update
369-
:data:`os.environ` with changes to the environment made by :func:`os.putenv`,
370-
by :func:`os.unsetenv`, or made outside Python in the same process.
368+
* Add the :func:`os.reload_environ` function to update :data:`os.environ` and
369+
:data:`os.environb` with changes to the environment made by
370+
:func:`os.putenv`, by :func:`os.unsetenv`, or made outside Python in the
371+
same process.
371372
(Contributed by Victor Stinner in :gh:`120057`.)
372373

373374

Lib/os.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -765,17 +765,6 @@ def __ror__(self, other):
765765
new.update(self)
766766
return new
767767

768-
if _exists("_create_environ"):
769-
def refresh(self):
770-
data = _create_environ()
771-
if name == 'nt':
772-
data = {self.encodekey(key): value
773-
for key, value in data.items()}
774-
775-
# modify in-place to keep os.environb in sync
776-
self._data.clear()
777-
self._data.update(data)
778-
779768
def _create_environ_mapping():
780769
if name == 'nt':
781770
# Where Env Var Names Must Be UPPERCASE
@@ -810,6 +799,20 @@ def decode(value):
810799
del _create_environ_mapping
811800

812801

802+
if _exists("_create_environ"):
803+
def reload_environ():
804+
data = _create_environ()
805+
if name == 'nt':
806+
encodekey = environ.encodekey
807+
data = {encodekey(key): value
808+
for key, value in data.items()}
809+
810+
# modify in-place to keep os.environb in sync
811+
env_data = environ._data
812+
env_data.clear()
813+
env_data.update(data)
814+
815+
813816
def getenv(key, default=None):
814817
"""Get an environment variable, return None if it doesn't exist.
815818
The optional second argument can specify an alternate default.

Lib/test/test_os.py

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

1301-
def test_refresh(self):
1302-
# Test os.environ.refresh()
1301+
def test_reload_environ(self):
1302+
# Test os.reload_environ()
13031303
has_environb = hasattr(os, 'environb')
13041304

13051305
# Test with putenv() which doesn't update os.environ
@@ -1309,7 +1309,7 @@ def test_refresh(self):
13091309
if has_environb:
13101310
self.assertEqual(os.environb[b'test_env'], b'python_value')
13111311

1312-
os.environ.refresh()
1312+
os.reload_environ()
13131313
self.assertEqual(os.environ['test_env'], 'new_value')
13141314
if has_environb:
13151315
self.assertEqual(os.environb[b'test_env'], b'new_value')
@@ -1320,28 +1320,28 @@ def test_refresh(self):
13201320
if has_environb:
13211321
self.assertEqual(os.environb[b'test_env'], b'new_value')
13221322

1323-
os.environ.refresh()
1323+
os.reload_environ()
13241324
self.assertNotIn('test_env', os.environ)
13251325
if has_environb:
13261326
self.assertNotIn(b'test_env', os.environb)
13271327

13281328
if has_environb:
1329-
# test os.environb.refresh() with putenv()
1329+
# test reload_environ() on os.environb with putenv()
13301330
os.environb[b'test_env'] = b'python_value2'
13311331
os.putenv("test_env", "new_value2")
13321332
self.assertEqual(os.environb[b'test_env'], b'python_value2')
13331333
self.assertEqual(os.environ['test_env'], 'python_value2')
13341334

1335-
os.environb.refresh()
1335+
os.reload_environ()
13361336
self.assertEqual(os.environb[b'test_env'], b'new_value2')
13371337
self.assertEqual(os.environ['test_env'], 'new_value2')
13381338

1339-
# test os.environb.refresh() with unsetenv()
1339+
# test reload_environ() on os.environb with unsetenv()
13401340
os.unsetenv('test_env')
13411341
self.assertEqual(os.environb[b'test_env'], b'new_value2')
13421342
self.assertEqual(os.environ['test_env'], 'new_value2')
13431343

1344-
os.environb.refresh()
1344+
os.reload_environ()
13451345
self.assertNotIn(b'test_env', os.environb)
13461346
self.assertNotIn('test_env', os.environ)
13471347

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Replace the ``os.environ.refresh()`` method with a new
2+
:func:`os.reload_environ` function. Patch by Victor Stinner.

0 commit comments

Comments
 (0)
0