On Sat, Jan 14, 2012 at 8:35 AM, Edward K. Ream <email address hidden> wrote:
> So the question is, how does docutils create the (weird) relative path::
>
> '../../../../../lib/site-packages/docutils/writers/html4css1/html4css1.css'
>
> One would think that this path would yield the desired .css file only
> if it was invoked five (!) levels below Python's lib directory. In
> other words, where do all the "../" come from?
I still don't know the answer to the question, but I'm pretty sure I
know where the path is computed and where the error message comes
from.
The message comes from the ctor of the FileInput class in the file
site-customize/docutils/io.py
The actual path,
'../../../../../lib/site-packages/docutils/writers/html4css1/html4css1.css',
most likely comes from the following very strange code at the start of
the Writer class in the file site-customize/docutils/__init__.py:
class Writer(writers.Writer):
supported = ('html', 'html4css1', 'xhtml')
"""Formats this writer supports."""
Note that this code is *not* in the ctor: the default_stylesheet_path
is a class var.
For me, this results in a full, absolute path name. I just now as I
write this see the call to utils.relative_path. Presumably this
creates all the '../' components of the path. Let's see...
def relative_path(source, target):
"""
Build and return a path to `target`, relative to `source` (both files).
If there is no common prefix, return the absolute path to `target`.
"""
source_parts = os.path.abspath(source or 'dummy_file').split(os.sep)
target_parts = os.path.abspath(target).split(os.sep)
# Check first 2 parts because '/dir'.split('/') == ['', 'dir']:
if source_parts[:2] != target_parts[:2]:
# Nothing in common between paths.
# Return absolute path, using '/' for URLs:
return '/'.join(target_parts)
source_parts.reverse()
target_parts.reverse()
while (source_parts and target_parts
and source_parts[-1] == target_parts[-1]):
# Remove path components in common: source_parts.pop() target_parts.pop()
target_parts.reverse()
parts = ['..'] * (len(source_parts) - 1) + target_parts
return '/'.join(parts)
Without understanding the code in detail, the last two lines do indeed
look like the source of the '../' components of the path.
In short, it looks like os.getcwd() is returning a path that results
in utils.relative_path returning
'../../../../../lib/site-packages/docutils/writers/html4css1/html4css1.css'
This is quite bizarre, imo. I wouldn't be surprised if this is a bug
in docutils. All this code seems too clever by half.
On Sat, Jan 14, 2012 at 8:35 AM, Edward K. Ream <email address hidden> wrote:
> So the question is, how does docutils create the (weird) relative path:: ../../. ./lib/site- packages/ docutils/ writers/ html4css1/ html4css1. css'
>
> '../../
>
> One would think that this path would yield the desired .css file only
> if it was invoked five (!) levels below Python's lib directory. In
> other words, where do all the "../" come from?
I still don't know the answer to the question, but I'm pretty sure I
know where the path is computed and where the error message comes
from.
The message comes from the ctor of the FileInput class in the file docutils/ io.py
site-customize/
The actual path, ../../. ./lib/site- packages/ docutils/ writers/ html4css1/ html4css1. css', docutils/ __init_ _.py:
'../../
most likely comes from the following very strange code at the start of
the Writer class in the file site-customize/
class Writer( writers. Writer) :
supported = ('html', 'html4css1', 'xhtml')
"""Formats this writer supports."""
default_ stylesheet = 'html4css1.css'
### g.pdb(' writer/ init.py' ) ### EKR.
default_ stylesheet_ path = utils.relative_ path(
os.path. join(os. getcwd( ), 'dummy'),
os.path. join(os. path.dirname( __file_ _), default_ stylesheet) )
Note that this code is *not* in the ctor: the default_ stylesheet_ path
is a class var.
For me, this results in a full, absolute path name. I just now as I path. Presumably this
write this see the call to utils.relative_
creates all the '../' components of the path. Let's see...
def relative_ path(source, target):
"""
Build and return a path to `target`, relative to `source` (both files).
If there is no common prefix, return the absolute path to `target`. abspath( source or 'dummy_ file'). split(os. sep) abspath( target) .split( os.sep) target_ parts) parts.reverse( ) parts.reverse( )
source_ parts.pop( )
target_ parts.pop( ) parts.reverse( )
"""
source_parts = os.path.
target_parts = os.path.
# Check first 2 parts because '/dir'.split('/') == ['', 'dir']:
if source_parts[:2] != target_parts[:2]:
# Nothing in common between paths.
# Return absolute path, using '/' for URLs:
return '/'.join(
source_
target_
while (source_parts and target_parts
and source_parts[-1] == target_parts[-1]):
# Remove path components in common:
target_
parts = ['..'] * (len(source_parts) - 1) + target_parts
return '/'.join(parts)
Without understanding the code in detail, the last two lines do indeed
look like the source of the '../' components of the path.
In short, it looks like os.getcwd() is returning a path that results ../../. ./lib/site- packages/ docutils/ writers/ html4css1/ html4css1. css'
in utils.relative_path returning
'../../
This is quite bizarre, imo. I wouldn't be surprised if this is a bug
in docutils. All this code seems too clever by half.
The question is, what to do about it.
Edward