pip install on a shared directory (windows)

2019-07-19 07:29发布

问题:

I've tried to create my own Pypi repository, respecting https://www.python.org/dev/peps/pep-0503/. My idea was to put it in a shared directory (I'm using Windows), say host1/my-pypi. I've generated the index.html needed:

(dir) host1\my-pypi
     -> (dir) toto
         (file) index.html
         (file) toto-1.0.0.whl
     -> (file) index.html

the index.html files look somehow normal (same as in the pep-503). I try, from another computer, say host2 that has access to this shared directory to install toto package using:

pip install --index-url file://host1/my-pipy toto

but it fails (when it tries to read the file with a OSError: [Errno 22] Invalid argument: '\\\\host1\\my-pypi\\').

First, has anyone tried (and solved) this before? (That's the easy solution :-) ).

Second, I've dug a little in the code of pip, and there are a couple of things that are unclear to me (if there's ever a pro in pip that can answer ;-) ).

  1. index.py, method find_all_candidates: it automatically changes my url list from [file://host1/my-pypi/toto], so it seems that it never tries to read host1\my-pypi\index.html... weird?

  2. index.py, method get_page: well point 1 is not blocking for me as it magically matches my architecture, but there's a weird condition:

    # Tack index.html onto file:// URLs that point to directories
    (scheme, netloc, path, params, query, fragment) = \
        urllib_parse.urlparse(url)
    if (scheme == 'file' and
            os.path.isdir(urllib_request.url2pathname(path))):
        # add trailing slash if not present so urljoin doesn't trim
        # final segment
        if not url.endswith('/'):
            url += '/'
        url = urllib_parse.urljoin(url, 'index.html')
        logger.debug(' file: URL is directory, getting %s', url)
    resp = session.get(
        url,
        headers={
            "Accept": "text/html",
            "Cache-Control": "max-age=600",
        },
    )
    

    well, as expected, we have:

    scheme = 'file'
    netloc = 'host1'
    path = '/my-pypi/'
    

    but the check condition os.path.isdir(urllib_request.url2pathname(path))) is obviously false as we've discarded the network location. Hence index.html is not appended to the path (that would've been correct otherwise), and hence the error while trying to read a file that does not exist.

回答1:

For a remote UNC file share, specify the file URL with four slashes:

pip install --index-url file:////host1/my-pypi toto

In this case, the parsed netloc is empty and the path still includes the server hostname in UNC format, so isdir works correctly and index.html will be appended as expected.