summaryrefslogtreecommitdiff
path: root/tests/test_import_machinery.py
blob: fc1ba7be21341bbee4bfd143f6a5abe05a664592 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab

from __future__ import absolute_import

import sys
import unittest

import gi.overrides
import gi.module
import gi.importer
from gi._compat import PY2, PY3

from gi.repository import Regress


class TestOverrides(unittest.TestCase):

    def test_non_gi(self):
        class MyClass:
            pass

        try:
            gi.overrides.override(MyClass)
            self.fail('unexpected success of overriding non-GI class')
        except TypeError as e:
            self.assertTrue('Can not override a type MyClass' in str(e))

    def test_separate_path(self):
        # Regress override is in tests/gi/overrides, separate from gi/overrides
        # https://bugzilla.gnome.org/show_bug.cgi?id=680913
        self.assertEqual(Regress.REGRESS_OVERRIDE, 42)

    def test_load_overrides(self):
        mod = gi.module.get_introspection_module('GIMarshallingTests')
        mod_override = gi.overrides.load_overrides(mod)
        self.assertTrue(mod_override is not mod)
        self.assertTrue(mod_override._introspection_module is mod)
        self.assertEqual(mod_override.OVERRIDES_CONSTANT, 7)
        self.assertEqual(mod.OVERRIDES_CONSTANT, 42)

    def test_load_no_overrides(self):
        mod_key = "gi.overrides.GIMarshallingTests"
        had_mod = mod_key in sys.modules
        old_mod = sys.modules.get(mod_key)
        try:
            # this makes override import fail
            sys.modules[mod_key] = None
            mod = gi.module.get_introspection_module('GIMarshallingTests')
            mod_override = gi.overrides.load_overrides(mod)
            self.assertTrue(mod_override is mod)
        finally:
            del sys.modules[mod_key]
            if had_mod:
                sys.modules[mod_key] = old_mod


class TestModule(unittest.TestCase):
    # Tests for gi.module

    def test_get_introspection_module_caching(self):
        # This test attempts to minimize side effects by
        # using a DynamicModule directly instead of going though:
        # from gi.repository import Foo

        # Clear out introspection module cache before running this test.
        old_modules = gi.module._introspection_modules
        gi.module._introspection_modules = {}

        mod_name = 'GIMarshallingTests'
        mod1 = gi.module.get_introspection_module(mod_name)
        mod2 = gi.module.get_introspection_module(mod_name)
        self.assertTrue(mod1 is mod2)

        # Restore the previous cache
        gi.module._introspection_modules = old_modules

    def test_module_dependency_loading(self):
        # Difficult to because this generally need to run in isolation to make
        # sure GIMarshallingTests has not yet been loaded. But we can do this with:
        #  make check TEST_NAMES=test_import_machinery.TestModule.test_module_dependency_loading
        if 'gi.repository.Gio' in sys.modules:
            return

        from gi.repository import GIMarshallingTests
        GIMarshallingTests  # PyFlakes

        self.assertIn('gi.repository.Gio', sys.modules)
        self.assertIn('gi.repository.GIMarshallingTests', sys.modules)

    def test_static_binding_protection(self):
        # Importing old static bindings once gi has been imported should not
        # crash but instead give back a dummy module which produces RuntimeErrors
        # on access.
        with self.assertRaises(AttributeError):
            import gobject
            gobject.anything

        with self.assertRaises(AttributeError):
            import glib
            glib.anything

        with self.assertRaises(AttributeError):
            import gio
            gio.anything

        with self.assertRaises(AttributeError):
            import gtk
            gtk.anything

        with self.assertRaises(AttributeError):
            import gtk.gdk
            gtk.gdk.anything


class TestImporter(unittest.TestCase):
    def test_invalid_repository_module_name(self):
        with self.assertRaises(ImportError) as context:
            from gi.repository import InvalidGObjectRepositoryModuleName
            InvalidGObjectRepositoryModuleName  # pyflakes

        exception_string = str(context.exception)

        self.assertTrue('InvalidGObjectRepositoryModuleName' in exception_string)

        # The message of the custom exception in gi/importer.py is eaten in Python <3.3
        if sys.version_info >= (3, 3):
            self.assertTrue('introspection typelib' in exception_string)

    def test_require_version_warning(self):
        check = gi.importer._check_require_version

        # make sure it doesn't fail at least
        with check("GLib", 1):
            from gi.repository import GLib
            GLib

        # make sure the exception propagates
        with self.assertRaises(ImportError):
            with check("InvalidGObjectRepositoryModuleName", 1):
                from gi.repository import InvalidGObjectRepositoryModuleName
                InvalidGObjectRepositoryModuleName

    def test_require_version_versiontype(self):
        import gi
        with self.assertRaises(ValueError):
            gi.require_version('GLib', 2.0)

        # Test that unicode strings work in python 2
        if PY2:
            gi.require_version('GLib', u'2.0')

        if PY3:
            with self.assertRaises(ValueError):
                gi.require_version('GLib', b'2.0')

    def test_require_versions(self):
        import gi
        gi.require_versions({'GLib': '2.0', 'Gio': '2.0', 'GObject': '2.0'})
        from gi.repository import GLib
        GLib

    def test_get_import_stacklevel(self):
        gi.importer.get_import_stacklevel(import_hook=True)
        gi.importer.get_import_stacklevel(import_hook=False)