classification
Title: os.path.abspath(None) behavior is inconsistent between platforms
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.2, Python 3.4, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: KevKeating, SilentGhost, martin.panter, pitrou, serhiy.storchaka
Priority: normal Keywords:

Created on 2014-10-09 16:56 by KevKeating, last changed 2019-03-16 09:00 by SilentGhost. This issue is now closed.

Messages (7)
msg228883 - (view) Author: Kevin Keating (KevKeating) Date: 2014-10-09 16:56
On Windows, os.path.abspath() treats None as if it were an empty string, so os.path.abspath(None) returns the current working directory.  On Linux, os.path.abspath(None) raises an AttributeError.  With macpath, abspath(None) raises a TypeError.  I've seen this behavior with Python 2.7.3, 2.7.8, 3.2.5, and 3.4.2.

Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:15:05) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ntpath, posixpath, macpath
>>> ntpath.abspath(None)
'C:\\Users\\Keating\\Documents'
>>> posixpath.abspath(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\programs\Python34\lib\posixpath.py", line 357, in abspath
    if not isabs(path):
  File "C:\programs\Python34\lib\posixpath.py", line 63, in isabs
    return s.startswith(sep)
AttributeError: 'NoneType' object has no attribute 'startswith'
>>> macpath.abspath(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\programs\Python34\lib\macpath.py", line 177, in abspath
    if not isabs(path):
  File "C:\programs\Python34\lib\macpath.py", line 49, in isabs
    return colon in s and s[:1] != colon
TypeError: argument of type 'NoneType' is not iterable

This case seems very closely related to http://bugs.python.org/issue9018, which noted a platform inconsistency in os.path.normcase.
msg228885 - (view) Author: Kevin Keating (KevKeating) Date: 2014-10-09 17:52
I just realized that even the behavior of ntpath.abspath() is inconsistent across platforms.  On Windows, ntpath.abspath(None) returns the current working directory.  On other OSs, ntpath.abspath(None) raises a TypeError.  There are two different abspath definitions in ntpath, one that uses the native Windows method (used on Windows) and one that doesn't (used everywhere else).  The two methods behave differently if the input value isn't a string.  I've tested this on OS X using Python 2.7.8 and 3.4.1:

Python 2.7.8 |Anaconda 2.1.0 (x86_64)| (default, Aug 21 2014, 15:21:46) 
[GCC 4.2.1 (Apple Inc. build 5577)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Anaconda is brought to you by Continuum Analytics.
Please check out: http://continuum.io/thanks and https://binstar.org
>>> import ntpath
>>> ntpath.abspath(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/young/anaconda/envs/py278/lib/python2.7/ntpath.py", line 473, in abspath
    if not isabs(path):
  File "/Users/young/anaconda/envs/py278/lib/python2.7/ntpath.py", line 57, in isabs
    s = splitdrive(s)[1]
  File "/Users/young/anaconda/envs/py278/lib/python2.7/ntpath.py", line 114, in splitdrive
    if len(p) > 1:
TypeError: object of type 'NoneType' has no len()


Python 3.4.1 |Anaconda 2.1.0 (x86_64)| (default, Sep 10 2014, 17:24:09) 
[GCC 4.2.1 (Apple Inc. build 5577)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ntpath
>>> ntpath.abspath(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/young/anaconda/envs/py34/lib/python3.4/ntpath.py", line 533, in abspath
if not isabs(path):
File "/Users/young/anaconda/envs/py34/lib/python3.4/ntpath.py", line 99, in isabs
s = splitdrive(s)[1]
File "/Users/young/anaconda/envs/py34/lib/python3.4/ntpath.py", line 159, in splitdrive
if len(p) > 1:
TypeError: object of type 'NoneType' has no len()
msg228997 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2014-10-10 13:16
I always assumed that None was a unwise value to pass to the “os.path” functions. Indeed, at the top of the documentation page it says they only accept bytes or (text) string parameters. Although returning a consistent error might be a sensible addition.
msg229008 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2014-10-10 15:11
It's because None quacks as empty string.
msg229026 - (view) Author: Kevin Keating (KevKeating) Date: 2014-10-10 19:45
I agree that None is an unwise value to pass in.  Of the four different abspath implementations, though, one will treat None (or any falsey value) as an empty string, while the other three will raise an exception unless passed an actual str or bytes object.  I think the ideal solution would be to have abspath(None) raise a TypeError regardless of operating system, which would make it consistent with normcase (http://bugs.python.org/issue9018).  It's conceivable that some Windows-only code might rely on the current behavior of abspath(None), though.
msg229027 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-10-10 19:54
+1 for raising TypeError, but I think this should only be changed in 3.5, since we don't want to break code in a bugfix release.
msg338068 - (view) Author: SilentGhost (SilentGhost) * (Python triager) Date: 2019-03-16 09:00
I'm closing this bug as fixed as TypeError is being raised on Linux on 3.7.2 (I think it was fixed for all platforms, due to work on path-like interface in 3.6). I don't think it's worth implementing this in 2.7 at this stage.
History
Date User Action Args
2019-03-16 09:00:27SilentGhostsetstatus: open -> closed

type: behavior

nosy: + SilentGhost
messages: + msg338068
resolution: fixed
stage: resolved
2014-10-10 19:54:27pitrousetnosy: + pitrou
messages: + msg229027
2014-10-10 19:45:45KevKeatingsetmessages: + msg229026
2014-10-10 15:11:43serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg229008
2014-10-10 13:16:34martin.pantersetnosy: + martin.panter
messages: + msg228997
2014-10-09 17:52:48KevKeatingsetmessages: + msg228885
2014-10-09 16:56:13KevKeatingcreate