-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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 1 commit
1daae93
ee4c4f6
f836691
89e1984
4bfb33c
963659a
cc1735f
d49fdf3
17386e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Co-authored-by: Marc Adam Anderson <marc@marcadam.com> .
- Loading branch information
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 |
---|---|---|
|
@@ -1252,6 +1252,48 @@ def tearDownClass(cls): | |
os.rmdir(support.TESTFN) | ||
|
||
|
||
class CurrentDirTests(unittest.TestCase): | ||
|
||
def setUp(self): | ||
self.pwd = os.environ['PWD'] | ||
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()) | ||
os.environ['PWD'] = self.tmp_dir | ||
self.assertEqual(self.tmp_dir, os.getcwd()) | ||
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): | ||
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) | ||
if os.name == 'posix': | ||
os.environ['PWD'] = self.tmp_lnk | ||
self.assertEqual(self.tmp_lnk, os.get_current_dir_name()) | ||
else: | ||
os.environ['PWD'] = self.tmp_lnk | ||
self.assertEqual(self.tmp_dir, os.get_current_dir_name()) | ||
os.unlink(self.tmp_lnk) | ||
|
||
def tearDown(self): | ||
os.environ['PWD'] = self.pwd | ||
|
||
|
||
class RemoveDirsTests(unittest.TestCase): | ||
def setUp(self): | ||
os.makedirs(support.TESTFN) | ||
|
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:
?