This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: os.path.normcase(None) does not raise an error on linux and should
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.2
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: ezio.melotti Nosy List: ezio.melotti, giampaolo.rodola, l0nwlf, orsenthil, pitrou, r.david.murray
Priority: normal Keywords: easy, patch

Created on 2010-06-17 13:40 by r.david.murray, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
issue9018.diff ezio.melotti, 2010-06-17 19:19 Simple testcase that fails on all the test_*path
issue9018-2.diff ezio.melotti, 2010-06-21 23:01 Patch against py3k + unittest + doc.
Messages (13)
msg108016 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-06-17 13:40
os.path.normcase(None) raises an error on Windows but returns None on linux.  os.path.abspath(None) raises an error in both cases.  os.path.normcase(None) should raise an error on linux.

I've only marked this for 3.2 because I suspect there may be linux code out there that this will break, so the fix should probably only be applied to 3.2.  (I discovered this because a unit test someone else wrote passed on linux but failed on windows.)
msg108049 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2010-06-17 19:19
Right now posixpath returns the argument unchanged, ntpath performs a .replace(), and macpath a .lower(), so when non-string (or non-bytes) are passed to normcase the results are:
posixpath: arg returned as-is;
ntpath: AttributeError (object has no attribute 'replace');
macpath: AttributeError (object has no attribute 'lower');

In posixpath we could reject all the non-string (and non-bytes) args, raising a TypeError. For consistency, the other functions should raise a TypeError too, but I'm not sure it's worth changing it.

Attached a simple testcase that checks that normcase raises a TypeError for invalid values with all the three implementations.
msg108050 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-06-17 19:23
> I've only marked this for 3.2 because I suspect there may be linux code 
> out there that this will break,

It should be noticed that Linux-only code has absolutely no point in using normcase(), since it's a no-op there.
msg108208 - (view) Author: Shashwat Anand (l0nwlf) Date: 2010-06-19 20:00
Following the documentation,
os.path.normcase(path)
Normalize the case of a pathname. On Unix and Mac OS X, this returns the path unchanged; on case-insensitive filesystems, it converts the path to lowercase. On Windows, it also converts forward slashes to backward slashes.

on Mac OS X,
>>> import os
>>> os.name
'posix'

Checking through, Lib/posixpath.py,

# Normalize the case of a pathname.  Trivial in Posix, string.lower on Mac.
# On MS-DOS this may also turn slashes into backslashes; however, other
# normalizations (such as optimizing '../' away) are not allowed                
# (another function should be defined to do that).

def normcase(s):
    """Normalize case of pathname.  Has no effect under Posix"""
    # TODO: on Mac OS X, this should really return s.lower().
    return s

Why on Mac OS X, it should return s.lower() ?
Also to raise Error for None case we can probably change normcase() in Lib/posixpath.py as,

def normcase(s):
    """Normalize case of pathname.  Has no effect under Posix"""
    if s is None:  
        raise AttributeError
    return s
msg108297 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2010-06-21 18:44
On Sat, Jun 19, 2010 at 08:00:55PM +0000, Shashwat Anand wrote:
> Why on Mac OS X, it should return s.lower() ?

That is is because some file systems on Mac OS X are case-sensitive.

> def normcase(s):
>     """Normalize case of pathname.  Has no effect under Posix"""
>     if s is None:  
>         raise AttributeError
>     return s

It should be a TypeError, not AttributeError. (Attached Test cases
checks it properly)
msg108319 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2010-06-21 21:32
ntpath and macpath raise an AttributeError, so we could:
1) change them all to accept only bytes/str and raise a TypeError for other wrong types (correct, consistent, non-backward-compatible);
2) change only posixpath to raise a TypeError for wrong types (partially correct, inconsistent, backward-compatible);
3) change only posixpath to raise an AttributeError for wrong types (wrong, consistent, backward-compatible);

The option 2 is still an improvement over the current situation, but it would be better to find a backward-compatible way to also obtain option 1 (assuming that backward compatibility is a concern here -- and I think it is (even though people could just change the code to catch (AttributeError, TypeError) and eventually get rid of the AttributeError)).
msg108320 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-06-21 21:39
> ntpath and macpath raise an AttributeError, so we could:
> 1) change them all to accept only bytes/str and raise a TypeError for
> other wrong types (correct, consistent, non-backward-compatible);

Sounds like the best thing to do.

> The option 2 is still an improvement over the current situation, but
> it would be better to find a backward-compatible way to also obtain
> option 1 (assuming that backward compatibility is a concern here --
> and I think it is (even though people could just change the code to
> catch (AttributeError, TypeError) and eventually get rid of the
> AttributeError)).

This isn't an exception you catch at runtime. It's an exception you get
when your code is wrong, and then you fix your code. Therefore I don't
think backwards compatibility is important.
msg108329 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2010-06-21 23:01
Here is the patch.
msg108335 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2010-06-22 03:46
Nice patch. I like the use of new string formating. It can be applied.
 
BTW, do you think that TODO of s.lower() for MAC OS X should be addressed along with this. It might require some research as how much of a desirable behavior it would be.
msg108416 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-06-22 21:05
My understanding is that there is a deep problem here, in that file system case (and in some cases encoding) is not OS/platform dependent, but is rather *file system* dependent.

Adding lower to normcase on OS X is probably not going to break much code (he says with no evidence to back it up), but someday it would be nice to address the various file system type dependencies in the os module :(

In any case, it is probably better to address the 'lower' issue in a separate issue/patch.
msg108424 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-06-22 21:42
Ah, I see my lack of knowledge of OS X has betrayed me.  Apparently you can set the case sensitivity of OS X file systems....so the deep problem is even deeper than I thought :(
msg108428 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2010-06-22 22:01
This problem should be addressed in another issue though.
msg108584 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2010-06-25 10:59
Fixed in r82214. Now os.path.normcase() raises a TypeError if the arg is not str or bytes.
History
Date User Action Args
2022-04-11 14:57:02adminsetgithub: 53264
2010-06-25 10:59:52ezio.melottisetstatus: open -> closed
resolution: fixed
messages: + msg108584

stage: patch review -> resolved
2010-06-22 22:01:01ezio.melottisetmessages: + msg108428
2010-06-22 21:42:31r.david.murraysetmessages: + msg108424
2010-06-22 21:05:59r.david.murraysetmessages: + msg108416
2010-06-22 03:46:02orsenthilsetmessages: + msg108335
2010-06-21 23:01:07ezio.melottisetfiles: + issue9018-2.diff

components: + Library (Lib)
assignee: ezio.melotti
keywords: + patch
nosy: orsenthil, pitrou, giampaolo.rodola, ezio.melotti, r.david.murray, l0nwlf
messages: + msg108329
stage: needs patch -> patch review
2010-06-21 21:39:19pitrousetmessages: + msg108320
2010-06-21 21:32:15ezio.melottisetmessages: + msg108319
2010-06-21 18:44:54orsenthilsetnosy: + orsenthil
messages: + msg108297
2010-06-19 20:00:54l0nwlfsetnosy: + l0nwlf
messages: + msg108208
2010-06-17 19:23:43pitrousetnosy: + pitrou
messages: + msg108050
2010-06-17 19:20:18ezio.melottisetkeywords: - patch
2010-06-17 19:19:23ezio.melottisetfiles: + issue9018.diff
keywords: + patch
messages: + msg108049

stage: test needed -> needs patch
2010-06-17 14:21:37giampaolo.rodolasetnosy: + giampaolo.rodola
2010-06-17 13:41:22ezio.melottisetnosy: + ezio.melotti
2010-06-17 13:40:15r.david.murraycreate