'Dataclass equality fails in tests, but not outside of tests

This is a simplified view of my project:

test.sh
src/
  subtitle_item.py
  time_utils.py
tests/
  __init__.py
  test_subtitle_item.py

src/subtitle_item.py:

from dataclasses import dataclass
from time_utils import TimeBase

@dataclass(frozen=True)
class SubtitleItem:
    index: int
    start_time: TimeBase

    @staticmethod
    def load_from_text_item():
        return SubtitleItem(0, TimeBase())

if __name__ == "__main__":
    a = SubtitleItem(0, TimeBase())
    b = SubtitleItem.load_from_text_item()
    print(a == b)

src/time_utils.py:

from dataclasses import dataclass

@dataclass(frozen=True)
class TimeBase:
    hours:          int = 0

tests/test_subtitle_item.py:

import unittest
from src.subtitle_item import SubtitleItem
from src.time_utils import TimeBase

class SubtitleItemTest(unittest.TestCase):
    def testLoadFromText(self):
        res = SubtitleItem.load_from_text_item()
        exp = SubtitleItem(0, TimeBase())
        self.assertEqual(res, exp)

If run the above test with test.sh:

#!/bin/sh

PYTHONPATH=src/ python -m unittest discover -s tests/ -v

... it fails. However, if I run the same test without unittest in python src/subtitle_item.py, it succeeds.

If I get rid of the SubtitleItem.start_time field and adapt the unit test, it succeeds. Even though exp.start_time and res.start_time have exactly the same fields and they are all comparable for equality, the unittest sees exp.start_time != res.start_time.

I think this is because Python sees exp.start_time and res.start_time as different types in the unittest:

>>> print(type(res.start_time), type(exp.start_time))
<class 'time_utils.TimeBase'> <class 'src.time_utils.TimeBase'>

... yet they are imported from the same actual file. I'm thinking this is happening because I modified PYTHONPATH so the test can access modules in src/.

What is the recommended way to fix this? Should I adapt all code to import scripts with their absolute path from src/, and run the main code with PYTHONPATH=src/?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source