z3-src 503.3.0

Source distribution of the Z3 SMT solver, for use as a build dependency
Documentation
############################################
# Copyright (c) 2026 Microsoft Corporation
#
# Unit tests for z3core.py library loading generation.
############################################
import io
import os
import sys
import unittest

# Add the scripts directory to the path so we can import update_api
_SCRIPTS_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if _SCRIPTS_DIR not in sys.path:
    sys.path.insert(0, _SCRIPTS_DIR)

import update_api

class TestZ3PyLibraryLoading(unittest.TestCase):
    def _render_preamble(self, soversion):
        buf = io.StringIO()
        update_api.write_core_py_preamble(buf, soversion)
        update_api.write_core_py_post(buf)
        return buf.getvalue()

    def test_linux_loader_uses_soversion_when_available(self):
        text = self._render_preamble("5.0")
        self.assertIn("_sover = '5.0'", text)
        self.assertIn("sys.platform.startswith('linux') and _sover", text)
        # Should have a fallback list with both versioned and unversioned names
        self.assertIn("_lib_names", text)
        self.assertIn("del _lib_names", text)
        self.assertIn('raise Z3Exception("%s not found." % _lib_name)', text)

    def test_linux_loader_falls_back_to_unversioned(self):
        text = self._render_preamble("5.0")
        # The loader should try multiple names (versioned + unversioned fallback)
        self.assertIn("for _name in _lib_names:", text)
        self.assertIn("d = os.path.join(d, _name)", text)
        self.assertIn("_lib = ctypes.CDLL(_name)", text)

    def test_loader_falls_back_to_unsuffixed_name_without_soversion(self):
        text = self._render_preamble(None)
        self.assertIn("_sover = None", text)
        self.assertIn(
            "_lib_name = 'libz3.%s.%s' % (_ext, _sover) if sys.platform.startswith('linux') and _sover else 'libz3.%s' % _ext",
            text,
        )
        self.assertIn("del _lib_name", text)
        self.assertIn("del _sover", text)


if __name__ == '__main__':
    unittest.main()