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.

Author iszegedi
Recipients
Date 2007-04-28.20:27:21
SpamBayes Score
Marked as misclassified
Message-id
In-reply-to
Content

Here is what Posix standard says about pathnames:

"Base Definitions volume of IEEE Std 1003.1-2001, Section 3.266, Pathname.

A character string that is used to identify a file. In the context of IEEE Std 1003.1-2001, a pathname consists of, at most, {PATH_MAX} bytes, including the terminating null byte. It has an optional beginning slash, followed by zero or more filenames separated by slashes. A pathname may optionally contain one or more trailing slashes. Multiple successive slashes are considered to be the same as one slash."

And in the details:

"A pathname that contains at least one non-slash character and that ends with one or more trailing slashes shall be resolved as if a single dot character ( '.' ) were appended to the pathname."

So if I am not mistaken, according to the POSIX standard the example that you gave - '/etc/passwd/' - should be normalized to '/etc/passwd/.' That does not happen, indeed.

The reason for that is that in posixpath.py file the normpath() function is using a split('/') function to split up the path into smaller chunks, skips everything which is empty or '.' and at the end of the normpath() function it adds slash(es) only to the beginning of the string. 

As a test, I modified the normpath() function in the posixpath.py as follows:

--- clip ---

def normpath(path):
    """Normalize path, eliminating double slashes, etc."""
    if path == '':
        return '.'
    initial_slashes = path.startswith('/')
    # The next two lines were added by iszegedi
    path = path.rstrip()
    trailing_slash = path.endswith('/')
    # POSIX allows one or two initial slashes, but treats three or more
    # as single slash.
    if (initial_slashes and
        path.startswith('//') and not path.startswith('///')):
        initial_slashes = 2
    comps = path.split('/')
    new_comps = []
    for comp in comps:
        if comp in ('', '.'):
            continue
        if (comp != '..' or (not initial_slashes and not new_comps) or
             (new_comps and new_comps[-1] == '..')):
            new_comps.append(comp)
        elif new_comps:
            new_comps.pop()
    comps = new_comps
    path = '/'.join(comps)
    if initial_slashes:
        path = '/'*initial_slashes + path
    # The next two lines were added by iszegedi
    if trailing_slash:
        path = path + '/.'
    return path or '.'
  
-- clip --

So I added two lines (marked as "added by iszegedi" ) in the beginning to remove any trailing whitespaces and check whether the path ends with slash. Then at the end of the function I added another two lines to append '/.' to the end of the return value if the input path variable ended by slash

This works now fine.

What makes it a bit tricky is that python os module imports different xxxpath.py module depending on the host operating system. So it imports different modules for nt, for mac, for os2, for posix, etc.  The solution above works for posix, but the other modules need to be checked, to.
History
Date User Action Args
2007-08-23 14:53:26adminlinkissue1707768 messages
2007-08-23 14:53:26admincreate