xref: /aosp_15_r20/external/pytorch/test/package/test_mangling.py (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1*da0073e9SAndroid Build Coastguard Worker# Owner(s): ["oncall: package/deploy"]
2*da0073e9SAndroid Build Coastguard Worker
3*da0073e9SAndroid Build Coastguard Workerfrom io import BytesIO
4*da0073e9SAndroid Build Coastguard Worker
5*da0073e9SAndroid Build Coastguard Workerfrom torch.package import PackageExporter, PackageImporter
6*da0073e9SAndroid Build Coastguard Workerfrom torch.package._mangling import (
7*da0073e9SAndroid Build Coastguard Worker    demangle,
8*da0073e9SAndroid Build Coastguard Worker    get_mangle_prefix,
9*da0073e9SAndroid Build Coastguard Worker    is_mangled,
10*da0073e9SAndroid Build Coastguard Worker    PackageMangler,
11*da0073e9SAndroid Build Coastguard Worker)
12*da0073e9SAndroid Build Coastguard Workerfrom torch.testing._internal.common_utils import run_tests
13*da0073e9SAndroid Build Coastguard Worker
14*da0073e9SAndroid Build Coastguard Worker
15*da0073e9SAndroid Build Coastguard Workertry:
16*da0073e9SAndroid Build Coastguard Worker    from .common import PackageTestCase
17*da0073e9SAndroid Build Coastguard Workerexcept ImportError:
18*da0073e9SAndroid Build Coastguard Worker    # Support the case where we run this file directly.
19*da0073e9SAndroid Build Coastguard Worker    from common import PackageTestCase
20*da0073e9SAndroid Build Coastguard Worker
21*da0073e9SAndroid Build Coastguard Worker
22*da0073e9SAndroid Build Coastguard Workerclass TestMangling(PackageTestCase):
23*da0073e9SAndroid Build Coastguard Worker    def test_unique_manglers(self):
24*da0073e9SAndroid Build Coastguard Worker        """
25*da0073e9SAndroid Build Coastguard Worker        Each mangler instance should generate a unique mangled name for a given input.
26*da0073e9SAndroid Build Coastguard Worker        """
27*da0073e9SAndroid Build Coastguard Worker        a = PackageMangler()
28*da0073e9SAndroid Build Coastguard Worker        b = PackageMangler()
29*da0073e9SAndroid Build Coastguard Worker        self.assertNotEqual(a.mangle("foo.bar"), b.mangle("foo.bar"))
30*da0073e9SAndroid Build Coastguard Worker
31*da0073e9SAndroid Build Coastguard Worker    def test_mangler_is_consistent(self):
32*da0073e9SAndroid Build Coastguard Worker        """
33*da0073e9SAndroid Build Coastguard Worker        Mangling the same name twice should produce the same result.
34*da0073e9SAndroid Build Coastguard Worker        """
35*da0073e9SAndroid Build Coastguard Worker        a = PackageMangler()
36*da0073e9SAndroid Build Coastguard Worker        self.assertEqual(a.mangle("abc.def"), a.mangle("abc.def"))
37*da0073e9SAndroid Build Coastguard Worker
38*da0073e9SAndroid Build Coastguard Worker    def test_roundtrip_mangling(self):
39*da0073e9SAndroid Build Coastguard Worker        a = PackageMangler()
40*da0073e9SAndroid Build Coastguard Worker        self.assertEqual("foo", demangle(a.mangle("foo")))
41*da0073e9SAndroid Build Coastguard Worker
42*da0073e9SAndroid Build Coastguard Worker    def test_is_mangled(self):
43*da0073e9SAndroid Build Coastguard Worker        a = PackageMangler()
44*da0073e9SAndroid Build Coastguard Worker        b = PackageMangler()
45*da0073e9SAndroid Build Coastguard Worker        self.assertTrue(is_mangled(a.mangle("foo.bar")))
46*da0073e9SAndroid Build Coastguard Worker        self.assertTrue(is_mangled(b.mangle("foo.bar")))
47*da0073e9SAndroid Build Coastguard Worker
48*da0073e9SAndroid Build Coastguard Worker        self.assertFalse(is_mangled("foo.bar"))
49*da0073e9SAndroid Build Coastguard Worker        self.assertFalse(is_mangled(demangle(a.mangle("foo.bar"))))
50*da0073e9SAndroid Build Coastguard Worker
51*da0073e9SAndroid Build Coastguard Worker    def test_demangler_multiple_manglers(self):
52*da0073e9SAndroid Build Coastguard Worker        """
53*da0073e9SAndroid Build Coastguard Worker        PackageDemangler should be able to demangle name generated by any PackageMangler.
54*da0073e9SAndroid Build Coastguard Worker        """
55*da0073e9SAndroid Build Coastguard Worker        a = PackageMangler()
56*da0073e9SAndroid Build Coastguard Worker        b = PackageMangler()
57*da0073e9SAndroid Build Coastguard Worker
58*da0073e9SAndroid Build Coastguard Worker        self.assertEqual("foo.bar", demangle(a.mangle("foo.bar")))
59*da0073e9SAndroid Build Coastguard Worker        self.assertEqual("bar.foo", demangle(b.mangle("bar.foo")))
60*da0073e9SAndroid Build Coastguard Worker
61*da0073e9SAndroid Build Coastguard Worker    def test_mangle_empty_errors(self):
62*da0073e9SAndroid Build Coastguard Worker        a = PackageMangler()
63*da0073e9SAndroid Build Coastguard Worker        with self.assertRaises(AssertionError):
64*da0073e9SAndroid Build Coastguard Worker            a.mangle("")
65*da0073e9SAndroid Build Coastguard Worker
66*da0073e9SAndroid Build Coastguard Worker    def test_demangle_base(self):
67*da0073e9SAndroid Build Coastguard Worker        """
68*da0073e9SAndroid Build Coastguard Worker        Demangling a mangle parent directly should currently return an empty string.
69*da0073e9SAndroid Build Coastguard Worker        """
70*da0073e9SAndroid Build Coastguard Worker        a = PackageMangler()
71*da0073e9SAndroid Build Coastguard Worker        mangled = a.mangle("foo")
72*da0073e9SAndroid Build Coastguard Worker        mangle_parent = mangled.partition(".")[0]
73*da0073e9SAndroid Build Coastguard Worker        self.assertEqual("", demangle(mangle_parent))
74*da0073e9SAndroid Build Coastguard Worker
75*da0073e9SAndroid Build Coastguard Worker    def test_mangle_prefix(self):
76*da0073e9SAndroid Build Coastguard Worker        a = PackageMangler()
77*da0073e9SAndroid Build Coastguard Worker        mangled = a.mangle("foo.bar")
78*da0073e9SAndroid Build Coastguard Worker        mangle_prefix = get_mangle_prefix(mangled)
79*da0073e9SAndroid Build Coastguard Worker        self.assertEqual(mangle_prefix + "." + "foo.bar", mangled)
80*da0073e9SAndroid Build Coastguard Worker
81*da0073e9SAndroid Build Coastguard Worker    def test_unique_module_names(self):
82*da0073e9SAndroid Build Coastguard Worker        import package_a.subpackage
83*da0073e9SAndroid Build Coastguard Worker
84*da0073e9SAndroid Build Coastguard Worker        obj = package_a.subpackage.PackageASubpackageObject()
85*da0073e9SAndroid Build Coastguard Worker        obj2 = package_a.PackageAObject(obj)
86*da0073e9SAndroid Build Coastguard Worker        f1 = BytesIO()
87*da0073e9SAndroid Build Coastguard Worker        with PackageExporter(f1) as pe:
88*da0073e9SAndroid Build Coastguard Worker            pe.intern("**")
89*da0073e9SAndroid Build Coastguard Worker            pe.save_pickle("obj", "obj.pkl", obj2)
90*da0073e9SAndroid Build Coastguard Worker        f1.seek(0)
91*da0073e9SAndroid Build Coastguard Worker        importer1 = PackageImporter(f1)
92*da0073e9SAndroid Build Coastguard Worker        loaded1 = importer1.load_pickle("obj", "obj.pkl")
93*da0073e9SAndroid Build Coastguard Worker        f1.seek(0)
94*da0073e9SAndroid Build Coastguard Worker        importer2 = PackageImporter(f1)
95*da0073e9SAndroid Build Coastguard Worker        loaded2 = importer2.load_pickle("obj", "obj.pkl")
96*da0073e9SAndroid Build Coastguard Worker
97*da0073e9SAndroid Build Coastguard Worker        # Modules from loaded packages should not shadow the names of modules.
98*da0073e9SAndroid Build Coastguard Worker        # See mangling.md for more info.
99*da0073e9SAndroid Build Coastguard Worker        self.assertNotEqual(type(obj2).__module__, type(loaded1).__module__)
100*da0073e9SAndroid Build Coastguard Worker        self.assertNotEqual(type(loaded1).__module__, type(loaded2).__module__)
101*da0073e9SAndroid Build Coastguard Worker
102*da0073e9SAndroid Build Coastguard Worker    def test_package_mangler(self):
103*da0073e9SAndroid Build Coastguard Worker        a = PackageMangler()
104*da0073e9SAndroid Build Coastguard Worker        b = PackageMangler()
105*da0073e9SAndroid Build Coastguard Worker        a_mangled = a.mangle("foo.bar")
106*da0073e9SAndroid Build Coastguard Worker        # Since `a` mangled this string, it should demangle properly.
107*da0073e9SAndroid Build Coastguard Worker        self.assertEqual(a.demangle(a_mangled), "foo.bar")
108*da0073e9SAndroid Build Coastguard Worker        # Since `b` did not mangle this string, demangling should leave it alone.
109*da0073e9SAndroid Build Coastguard Worker        self.assertEqual(b.demangle(a_mangled), a_mangled)
110*da0073e9SAndroid Build Coastguard Worker
111*da0073e9SAndroid Build Coastguard Worker
112*da0073e9SAndroid Build Coastguard Workerif __name__ == "__main__":
113*da0073e9SAndroid Build Coastguard Worker    run_tests()
114