[Tutor] Why does os.path.realpath('test_main.py') give different results for unittest than for testing statement in interpreter?

boB Stepp robertvstepp at gmail.com
Sun Jan 7 04:07:26 EST 2018


On Sun, Jan 7, 2018 at 2:05 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sun, Jan 07, 2018 at 12:49:59AM -0600, boB Stepp wrote:
>
>> Win7, Python 3.6.2
>>
>> If I run a unit test with the following embedded:
>>
>> print('realpath =', os.path.realpath('test_main.py'))
>>
>> I get the following in my test output (Only relevant line is shown):
>>
>> Ensure expected list of string integers is returned. ...
>> realpath = c:\Projects\solitaire_scorekeeper\test_main.py
>
>
> realpath() returns the canonical path of the given filename. It doesn't
> try to locate some actual existing file. The fact that there is a file
> called "test_main.py" located here:
>
>> In actuality "test_main.py" is located at
>> "c:\Projects\solitaire_scorekeeper\tests\test_main.py"
>
> is irrelevent. You asked for the "real" (canonical) path name to the
> relative pathname "test_main.py". That means in the current directory,
> which apparently is C:\Projects\solitaire_scorekeeper. Hence you get the
> result C:\Projects\solitaire_scorekeeper\test_main.py even though the
> "real file" is one directory further in.

After some searching I have yet to locate a definition of "canonical
path" that makes sense to me.  The dictionary definition of canonical
does not seem to be very helpful in understanding this.  Can you
clarify this?  What is the methodology that os.path.realpath(path) is
actually following to yield a particular path name?  And why does it
not care if path refers to a real file or not?

What I *really* want to do is locate and open a file "test_data.dat"
that is in the same directory as the file with the tests,
"tests/test_main.py".  I asked a related question a while back but I
now suspect I did not fully get everything.  I have recently been
experimenting with the os and os.path modules and thought I had found
the magic bullet with os.path.realpath().  Anyway, based on that
earlier related question and your answer tonight I have modified my
test class to the following:

class TestOpenFileStrIntsToList(unittest.TestCase):
    """Tests for the function open_file_str_ints_to_list."""

    def test_open_file_str_ints_to_list(self):
        """Ensure expected list of string integers is returned."""

        path = os.path.dirname(
                os.path.realpath(__file__)) + '/test_data.dat'
        print('realpath =', os.path.realpath(__file__))
        expected_list = ['-3', '-2', '-1', '0', '1', '2', '3']
        self.assertEqual(open_file_str_ints_to_list(path), expected_list)

The test_data file is just the expected_list values, one value per
line in the file.  The function being tested is:

def open_file_str_ints_to_list(path):
    """Given a path to the file, open this file containing one string integer
    per line, and convert it to a list of string integers, which is then
    returned by this function."""

    with open(path) as infile:
        string_integers = [line.strip() for line in infile]

    return string_integers

BTW, I am having trouble coming up with a good name for a string that
looks like an integer that I plan on using int() later to convert the
string to an integer.  "String integer" is my best thought at this
time.

Anyway, the print() statement in the test case is giving me the
correct result.  Is this way of determining the directory which
test_main.py is running from bullet proof?


-- 
boB


More information about the Tutor mailing list