Re: Relative versus absolute paths on Windows

2009-11-23 Thread Jason R. Coombs
On Nov 20, 3:52 pm, Ethan Furman  wrote:
> It is often said on this list that 'Python is not Java'.  It is also
> true that 'Windows is not Unix'.
>
> Unlike the *nix world where there is a *single* root, and everything
> else is relative to that, in the Windows world there are several roots
> -- every drive has one!

I acknowledge that the Windows paradigm is messy and less elegant than
Unix. I'm not trying to place blame here. I pointed out that even the
Windows interfaces don't seem to provide the functions needed to do
what I want to do. However, my point is that there is a need for path
resolution that respects a rooted path as relative to another path.

> So \bar is both an absolute path on whichever drive is active (or
> specified), as well as relative if you happen to have more than one
> drive, but it will not ever be relative on any specific drive.  If you
> want 'bar' to be relative to the current directory, do not specify a
> leading '\'.

Precisely. And my point is that if the path "specified" has a drive (d:
\foo) and one wants "\bar" relative to d:\foo, the result should be d:
\bar, not \bar, which is relative to the current drive.

I elaborate below.

> > Ultimately, I don't care what the definition is. It seems to me,
> > however, that Python should have a function that can resolve one path
> > name relative to another, but due to these limitations, it does not. I
> > should point out that os.path.relpath is not the solution either as
> > the first parameter is always treated as relative to the current
> > directory (more info athttp://bugs.python.org/issue7195).
>
> Please note that there *is not* a relative path that can take you from
> c:\foo to d:\bar  (see the point about multiple roots above).

I'm not looking for a relative path from c:\foo to d:\bar. I know the
"shortest relative path" from c:\foo to d:\bar is the absolute path d:
\bar. What I am looking for is a way to resolve one path relative to
another irrespective of the current directory.

Here's the use case: A symlink or shortcut (they can both be treated
for symbolic links for the sake of this discussion) is defined in a
particular location, let's say d:\foo. This symlink points to "\bar".

On Windows, the target of the symlink is treated as relative to the
location of the symlink itself, not the current directory when
accessed. In other words, \bar relative to d:\foo always resolves to d:
\bar. To effectively track down the target of a symbolic link, it
becomes necessary to perform this resolution.

> > What is the benefit of treating \path as absolute?
>
> That was not Python's decision, but Windows'.

Maybe so. My feeling is there's a good reason for it, based on the
multiple implementations that follow the same approach. Nevertheless,
that doesn't change the fact that despite the APIs, Windows does
internally resolve symlinks relative to the symlink location.

> > Should Python have built-in support for resolving one path relative to
> > another (such as is jaraco.windows.filesystem.resolve_path does)?
>
> As I noted above, you are not returning a relative path when the paths
> cross drive letter boundaries, or one of the paths specified is a
> drive-absolute path (such as '\bar').

To be clear, I'm not trying to find a relative path between two paths.
I'm trying to resolve one path relative to another. On Unix,
os.path.join does this. On Windows, there is no such function (except
jaraco.windows.filesystem.join).

> Hope this helps.

Thanks for taking the time to write a detailed response. I think I
understand the problem. What is frustrating is that the current
behavior seems buggy (others words, not mine) and a function that does
what many would expect isn't available.

> P.S.
> And now that I look up the comments in the bug-tracker, I see this was
> all already pointed out to you.

Based on the name and specification, I expected something different
from relpath, but after the discussion, I decided it wasn't the tool I
was seeking.
-- 
http://mail.python.org/mailman/listinfo/python-list


Relative versus absolute paths on Windows

2009-11-20 Thread Jason R. Coombs
The current implementation of Python (2.6.4, 3.1.1) treats \bar as a
relative path but reports it as an absolute path.

>>> ntpath.isabs('\\bar')
True
>>> ntpath.abspath('\\bar')
'C:\\bar'
>>> os.chdir('d:\\')
>>> ntpath.abspath('\\bar')
'd:\\bar'
>>> os.chdir('server\\share')
>>> ntpath.abspath('\\bar')
'server\\share\\bar'

In other words, paths without a drive letter are reported as absolute,
but treated as relative, except in a few special cases.

>>> ntpath.join('d:\\foo', '\\bar')
'\\bar'

In this case, \bar is treated as absolute, and not relative to d:\foo.

This inconsistency means that to effectively resolve one path relative
to another, one has to resort to explicit drive letter manipulation.
See 
http://stackoverflow.com/questions/1654659/find-a-path-in-windows-relative-to-another
for a case in point.

My understanding is that in Windows, a path is only absolute if it
contains a drive letter or it begins with a double-backslash.

Curiously, the .Net Framework seems to be subject to the same
limitation

# using IronPython 2.6RC2
>>> System.IO.Path.IsPathRooted('\\bar')
True
>>> System.IO.Path.Combine('d:\\foo', '\\bar') # expect d:\bar
'\\bar'

The documentation for Combine raises this issue in the Community
Content (http://msdn.microsoft.com/en-us/library/fyy7a5kt.aspx).

Furthermore, the Windows API utility is also consistent with this odd
behavior (http://msdn.microsoft.com/en-us/library/bb773660%28VS.
85%29.aspx).

The discussion here (http://groups.google.com/group/comp.os.ms-
windows.programmer.win32/browse_thread/thread/b2ff7a9d1d7c9b5e)
describes absolute paths consistent with my understanding:

  Absolute paths have these characteristics.
  Length is at least 2 characters, AND
  ( Second character is ":", OR First two characters is "\\" )

And according to WikiPedia (http://en.wikipedia.org/wiki/Path_
%28computing%29), "[an] absolute path is a path that points to the
same location on one file system regardless of the working directory."
By this definition, \bar is a relative path on Windows.

Ultimately, I don't care what the definition is. It seems to me,
however, that Python should have a function that can resolve one path
name relative to another, but due to these limitations, it does not. I
should point out that os.path.relpath is not the solution either as
the first parameter is always treated as relative to the current
directory (more info at http://bugs.python.org/issue7195).

I've built workarounds in 
https://svn.jaraco.com/jaraco/python/jaraco.windows/jaraco/windows/filesystem.py
as join() and resolve_path(). I'm happy to continue using these
workarounds, but I wanted to bring this issue to the attention of the
community for any comments or suggestions or answers to the following
questions.

What is the benefit of treating \path as absolute?
Should Python have built-in support for resolving one path relative to
another (such as is jaraco.windows.filesystem.resolve_path does)?
Given the long established behavior of Python and other platforms for
handling absolute paths in Windows, is there a way forward that
handles these cases more elegantly, or is the best approach to just
mumble something nasty under our breath and work around these issues
on a case-by-case basis?
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: namedtuple suggestions

2008-06-13 Thread Jason R. Coombs
I also agree with your point on concatting.  I used that syntax because it
seemed more clear, given the already awkward syntax.

And while the original motivation of namedtuple might be to avoid having to
make a class or subclass, subclasses have already emerged even within the
standard library (see lib/urlparse for a prime example of extending the
namedtuple class).

Regards,
Jason

-Original Message-
From: Calvin Spealman [mailto:[EMAIL PROTECTED] 
Sent: Friday, 13 June, 2008 12:17
To: Jason R. Coombs
Cc: python-list@python.org
Subject: Re: namedtuple suggestions

On Jun 13, 2008, at 11:17 AM, Jason R. Coombs wrote:

> I see a new function in (python 2.6) lib/collections called
> namedtuple.  This is a great function.  I can see many places in my
> code where this will be immensely useful.
>
> I have a couple of suggestions.
>
> My first suggestion is to use self.__class__.__name__ instead of the
> hard-coded typename in __repr__, so that subclasses don't have to
> override these methods just to use the correct name.
>
> def __repr__(self):
> return self.__class__.__name__ + '(%(reprtxt)s)' %% self
> \n

I feel like a large point of NamedTuple is for those cases where you  
need a small object with some attributes _without_ creating a  
subclass. Useful for mocks, for example, or when you need to trick a  
function into dealing with a quick proxy or stub. If a large point is  
not needing to create a class but instead creating a cheap object,  
should it be a good idea to then subclass the very thing that was  
intended to help you avoid creating a class in the first place? What  
do you gain subclassing it?

However, I always think a repr reflecting a type name should reflect  
the correct type, so I'm not disagreeing on that point. But, just  
don't use concating :-)


smime.p7s
Description: S/MIME cryptographic signature
--
http://mail.python.org/mailman/listinfo/python-list

namedtuple suggestions

2008-06-13 Thread Jason R. Coombs
I see a new function in (python 2.6) lib/collections called
namedtuple.  This is a great function.  I can see many places in my
code where this will be immensely useful.

I have a couple of suggestions.

My first suggestion is to use self.__class__.__name__ instead of the
hard-coded typename in __repr__, so that subclasses don't have to
override these methods just to use the correct name.

def __repr__(self):
return self.__class__.__name__ + '(%(reprtxt)s)' %% self
\n

My other suggestion, which is perhaps more intrusive, would be to
implement the underlying class as a metaclass, rather than
constructing and exec'ing a string.  This would make the code more
readable (as there wouldn't be format string substitions in the class
definition, and the code could be interpreted by editors for syntax
highlighting, indentation support, etc).

I'm willing to take up the latter effort if there's agreement this
could be included in the release.

Regards,
Jason R. Coombs
--
http://mail.python.org/mailman/listinfo/python-list


Wording suggestion for documentation (Data Model)

2008-06-12 Thread Jason R. Coombs
#!python

"""
In the documentation for __del__ (under Python Language Reference/Data
Model), the following warning is indicated:

Warning [Caveat in 2.6]: Due to the precarious circumstances under
which __del__() methods are invoked, exceptions that occur during
their execution are ignored, and a warning is printed to sys.stderr
instead. ...

That statement appears, however, to be incorrect.

Perhaps the warning should be re-worded to say "When __del__() methods
are invoked, exceptions that occur during the execution of such
methods must be caught and handled within the scope of the __del__()
method call.  Otherwise unhandled exceptions will be ignored except
for a warning printed to sys.stderr instead."

For example,
"""

class X(object):
def __del__(self):
print 'deleting', self
try:
raise Exception, "OMG!"
except:
print 'caught exception, np'
print 'made it past the exception'

x = X()
del x

print 'x has been deleted, now what?'

"""
All this prints something like:

deleting <__main__.X object at 0x01BB1A50>
caught exception, np
made it past the exception
x has been deleted, now what?
"""

# - Jason R. Coombs
--
http://mail.python.org/mailman/listinfo/python-list