-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
bpo-1154351: Add get_current_dir_name() to os module #10117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
1daae93
ee4c4f6
f836691
89e1984
4bfb33c
963659a
cc1735f
d49fdf3
17386e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -155,6 +155,7 @@ process and user. | |
.. function:: chdir(path) | ||
fchdir(fd) | ||
getcwd() | ||
get_current_dir_name() | ||
:noindex: | ||
|
||
These functions are described in :ref:`os-file-dir`. | ||
|
@@ -1698,6 +1699,19 @@ features: | |
Return a bytestring representing the current working directory. | ||
|
||
|
||
.. function:: get_current_dir_name() | ||
|
||
Return a string representing the current working directory taking into | ||
consideration the users ``PWD`` environment variable if it exists. This is | ||
opposed to :func:`getcwd()` which dereferences symlinks in the path. This | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove |
||
function is identical to :func:`getcwd()` on systems that do **not** | ||
support the ``PWD`` environment variable. | ||
|
||
.. availability:: Unix. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function is available on all platforms. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, while this is undoubtably an ancient link ( https://www.gnu.org/software/gnulib/manual/html_node/get_005fcurrent_005fdir_005fname.html ) I do not believe this function is available in all POSIX environments. It may be common in GNU runtime environments. FYI: I just checked AIX and found the routine name "exists" in AIX <unistd.h>, but there is no documentation. So, it seems it may be visible on AIX, even if they have never taken the time to a is adding dd it to the getcwd() manual page. Confusion #1 in adding this |
||
|
||
.. versionadded:: 3.8 | ||
|
||
|
||
.. function:: lchflags(path, flags) | ||
|
||
Set the flags of *path* to the numeric *flags*, like :func:`chflags`, but do | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,7 +32,7 @@ | |
__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", | ||
"defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR", | ||
"SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen", | ||
"popen", "extsep"] | ||
"popen", "extsep", "get_current_dir_name"] | ||
|
||
def _exists(name): | ||
return name in globals() | ||
|
@@ -651,6 +651,29 @@ def get_exec_path(env=None): | |
return path_list.split(pathsep) | ||
|
||
|
||
def get_current_dir_name(): | ||
""" | ||
Return a string representing the current working directory taking into | ||
consideration the users *PWD* environment variable if it exists. This | ||
is opposed to getcwd() which dereferences symlinks in the path. This | ||
function is identical to getcwd() on systems that do *not* support | ||
the *PWD* environment variable. | ||
""" | ||
cwd = getcwd() | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think empty lines in this functions are redundant. Empty lines inside functions are used for separating groups of statements in large functions, but this function is enough small and simple. And will be smaller after removing empty lines. |
||
try: | ||
pwd = environ["PWD"] | ||
except KeyError: | ||
return cwd | ||
|
||
cwd_stat, pwd_stat = map(stat, [cwd, pwd]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be clearer just to write two stat calls. |
||
|
||
if (cwd_stat.st_dev == pwd_stat.st_dev and | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe use samefile()? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, confusion #2 -, assuming that get_current_dir_name() is supported by the platform why is that not just being called rather than rewriting it? I admit my confusion comes from the lack of platform documentation, but why so hard? Wouldn't calling the "platform" implementation be more efficient than writing this in "pure" python. More simply, why not use the platform implementation, perhaps adding it to posixmodule.c rather than here? |
||
cwd_stat.st_ino == pwd_stat.st_ino): | ||
return pwd | ||
return cwd | ||
|
||
|
||
# Change environ to automatically call putenv(), unsetenv if they exist. | ||
from _collections_abc import MutableMapping | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ | |
import uuid | ||
import warnings | ||
from test import support | ||
from unittest import mock | ||
|
||
try: | ||
import resource | ||
|
@@ -1252,6 +1253,43 @@ def tearDownClass(cls): | |
os.rmdir(support.TESTFN) | ||
|
||
|
||
class CurrentDirTests(unittest.TestCase): | ||
|
||
def setUp(self): | ||
base = os.path.abspath(support.TESTFN) | ||
self.tmp_dir = base + '_dir' | ||
self.tmp_lnk = base + '_lnk' | ||
|
||
def test_getcwd(self): | ||
# os.getcwd() always returns the dereferenced path | ||
with support.temp_cwd(self.tmp_dir): | ||
os.chdir(self.tmp_dir) | ||
self.assertEqual(self.tmp_dir, os.getcwd()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Swap arguments. The first argument is an actual value, the second argument is an expected value. |
||
os.symlink(self.tmp_dir, self.tmp_lnk, True) | ||
os.chdir(self.tmp_lnk) | ||
self.assertEqual(self.tmp_dir, os.getcwd()) | ||
with mock.patch.dict('os.environ', {'PWD': self.tmp_dir}): | ||
self.assertEqual(self.tmp_dir, os.getcwd()) | ||
with mock.patch.dict('os.environ', {'PWD': self.tmp_lnk}): | ||
self.assertEqual(self.tmp_dir, os.getcwd()) | ||
os.unlink(self.tmp_lnk) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The link will be leaked in the case of failure. It is better to use self.addCleanup(support.unlink, self.tmp_lnk) |
||
|
||
def test_get_current_dir_name(self): | ||
# os.get_current_dir_name() returns the direct path--mirroring | ||
# the PWD environment variable if it exists regardless of | ||
# whether the path contains symlinks. | ||
with support.temp_cwd(self.tmp_dir): | ||
with mock.patch.dict('os.environ', {'PWD': self.tmp_dir}): | ||
self.assertEqual(self.tmp_dir, os.get_current_dir_name()) | ||
os.symlink(self.tmp_dir, self.tmp_lnk, True) | ||
with mock.patch.dict('os.environ', {'PWD': self.tmp_lnk}): | ||
if os.name == 'posix': | ||
self.assertEqual(self.tmp_lnk, os.get_current_dir_name()) | ||
else: | ||
self.assertEqual(self.tmp_dir, os.get_current_dir_name()) | ||
os.unlink(self.tmp_lnk) | ||
|
||
|
||
class RemoveDirsTests(unittest.TestCase): | ||
def setUp(self): | ||
os.makedirs(support.TESTFN) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add get_current_dir_name() to the os module. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Patch by ..." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use
:envvar:
?