Search code examples
directorypython-3.6docxpywin32

Having problems with accessing files on a mapped network drive, using pywin32 client


I am currently using the following code to open up a word document (and then save it but that is irrelevant to opening the file at the moment):

    word=win32.Dispatch('Word.Application')
    try:                      
    doc = word.Documents.Open('S:\problem\file.docx')
    except Exception as e:
    print(e)

    (-2147352567, 'Exception occurred.', (0, 'Microsoft Word', 'Sorry, we 
    couldn’t find your file. Is it possible it was moved, renamed or 
    deleted?\r (S:\\problem\\file.docx)', 
    'wdmain11.chm', 24654, -2146823114), None)

The "problem" directory is the only directory it seems the win32 client is not able to recognize. I have renamed it several times to even single letters to see if the naming was the problem for some reason, but that does not seem to be the problem.

The file path is also recognized by the docx function- docx.Document and it is able to read the files in the directory. Here is the same code and results for the docx snippet:

    Document('S://problem/file.docx')
    <docx.document.Document at 0x83d3c18>

Solution

  • In Python strings, bkslash ("\") is one of the characters with a special meaning: it's used to create escape sequences (special chars) together with the char that follows it (this comes from C). Here's what [Python 3]: String and Bytes literals states:

    The backslash (\) character is used to escape characters that otherwise have a special meaning, such as newline, backslash itself, or the quote character.

    In your string, you have "\p" (which is OK) and "\f" which is interpreted as a single char (form feed - new page), making your path invalid.

    In order to fix this, either:

    • Escape (double) any "\" in the string (well, this is just a precaution measure since you only have to escape the ones that produce an escape sequence - in our example, "\p" is perfectly fine), except the ones that you want to produce an escape sequence: 'S:\problem\file.docx'
    • Make the string raw, by prepending it with the r marker (note that if the string ends with a "\", that should still be escaped, otherwise it will escape the string ending marker (' or ") that comes after it, yielding SyntaxError): r'S:\problem\file.docx'

    As a general rule, in order to ensure that strings are what you think they are, either:

    • Check their length: if it's smaller than the number of chars you see (in the code), it means that there is at least one escape sequence
    • Use repr

    Example:

    >>> import sys
    >>> sys.version
    '3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)]'
    >>>
    >>> s0 = 'S:\problem\file.docx'
    >>> s1 = 'S:\\problem\\file.docx'
    >>> s2 = r'S:\problem\file.docx'
    >>>
    >>> len(s0), len(s1), len(s2)
    (19, 20, 20)
    >>>
    >>> s0 == s1, s1 == s2
    (False, True)
    >>>
    >>> repr(s0), repr(s1), repr(s2)
    ("'S:\\\\problem\\x0cile.docx'", "'S:\\\\problem\\\\file.docx'", "'S:\\\\problem\\\\file.docx'")