11ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchakaimport imghdr
21ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchakaimport io
31ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchakaimport os
4ef223a19f76101a914ccff8b4690d9e4717e109eBerker Peksagimport pathlib
51ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchakaimport unittest
61ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchakaimport warnings
71ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchakafrom test.support import findfile, TESTFN, unlink
81ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
91ac00950b28e91fc35fed6445722ade92732648eSerhiy StorchakaTEST_FILES = (
101ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    ('python.png', 'png'),
111ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    ('python.gif', 'gif'),
121ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    ('python.bmp', 'bmp'),
131ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    ('python.ppm', 'ppm'),
141ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    ('python.pgm', 'pgm'),
151ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    ('python.pbm', 'pbm'),
161ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    ('python.jpg', 'jpeg'),
171ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    ('python.ras', 'rast'),
181ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    ('python.sgi', 'rgb'),
191ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    ('python.tiff', 'tiff'),
202f8dca735e9e30aab6cea2270875021b3098bd2aSerhiy Storchaka    ('python.xbm', 'xbm'),
212f8dca735e9e30aab6cea2270875021b3098bd2aSerhiy Storchaka    ('python.webp', 'webp'),
222f60820f4c1bdfce75f30ddc53d97587a3256dcfR David Murray    ('python.exr', 'exr'),
231ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka)
241ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
251ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchakaclass UnseekableIO(io.FileIO):
261ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def tell(self):
271ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        raise io.UnsupportedOperation
281ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
291ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def seek(self, *args, **kwargs):
301ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        raise io.UnsupportedOperation
311ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
321ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchakaclass TestImghdr(unittest.TestCase):
331ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    @classmethod
341ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def setUpClass(cls):
351ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        cls.testfile = findfile('python.png', subdir='imghdrdata')
361ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with open(cls.testfile, 'rb') as stream:
371ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            cls.testdata = stream.read()
381ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
391ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def tearDown(self):
401ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        unlink(TESTFN)
411ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
421ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def test_data(self):
431ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        for filename, expected in TEST_FILES:
441ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            filename = findfile(filename, subdir='imghdrdata')
451ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            self.assertEqual(imghdr.what(filename), expected)
461ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            with open(filename, 'rb') as stream:
471ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                self.assertEqual(imghdr.what(stream), expected)
481ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            with open(filename, 'rb') as stream:
491ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                data = stream.read()
501ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            self.assertEqual(imghdr.what(None, data), expected)
511ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            self.assertEqual(imghdr.what(None, bytearray(data)), expected)
521ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
53ef223a19f76101a914ccff8b4690d9e4717e109eBerker Peksag    def test_pathlike_filename(self):
54ef223a19f76101a914ccff8b4690d9e4717e109eBerker Peksag        for filename, expected in TEST_FILES:
55ef223a19f76101a914ccff8b4690d9e4717e109eBerker Peksag            with self.subTest(filename=filename):
56ef223a19f76101a914ccff8b4690d9e4717e109eBerker Peksag                filename = findfile(filename, subdir='imghdrdata')
57ef223a19f76101a914ccff8b4690d9e4717e109eBerker Peksag                self.assertEqual(imghdr.what(pathlib.Path(filename)), expected)
58ef223a19f76101a914ccff8b4690d9e4717e109eBerker Peksag
591ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def test_register_test(self):
601ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        def test_jumbo(h, file):
611ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            if h.startswith(b'eggs'):
621ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                return 'ham'
631ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        imghdr.tests.append(test_jumbo)
641ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        self.addCleanup(imghdr.tests.pop)
651ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        self.assertEqual(imghdr.what(None, b'eggs'), 'ham')
661ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
671ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def test_file_pos(self):
681ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with open(TESTFN, 'wb') as stream:
691ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            stream.write(b'ababagalamaga')
701ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            pos = stream.tell()
711ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            stream.write(self.testdata)
721ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with open(TESTFN, 'rb') as stream:
731ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            stream.seek(pos)
741ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            self.assertEqual(imghdr.what(stream), 'png')
751ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            self.assertEqual(stream.tell(), pos)
761ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
771ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def test_bad_args(self):
781ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with self.assertRaises(TypeError):
791ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            imghdr.what()
801ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with self.assertRaises(AttributeError):
811ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            imghdr.what(None)
821ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with self.assertRaises(TypeError):
831ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            imghdr.what(self.testfile, 1)
841ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with self.assertRaises(AttributeError):
851ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            imghdr.what(os.fsencode(self.testfile))
861ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with open(self.testfile, 'rb') as f:
871ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            with self.assertRaises(AttributeError):
881ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                imghdr.what(f.fileno())
891ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
901ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def test_invalid_headers(self):
911ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        for header in (b'\211PN\r\n',
921ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                       b'\001\331',
931ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                       b'\x59\xA6',
941ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                       b'cutecat',
951ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                       b'000000JFI',
961ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                       b'GIF80'):
971ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            self.assertIsNone(imghdr.what(None, header))
981ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
991ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def test_string_data(self):
1001ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with warnings.catch_warnings():
1011ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            warnings.simplefilter("ignore", BytesWarning)
1021ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            for filename, _ in TEST_FILES:
1031ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                filename = findfile(filename, subdir='imghdrdata')
1041ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                with open(filename, 'rb') as stream:
1051ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                    data = stream.read().decode('latin1')
1061ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                with self.assertRaises(TypeError):
1071ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                    imghdr.what(io.StringIO(data))
1081ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                with self.assertRaises(TypeError):
1091ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                    imghdr.what(None, data)
1101ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
1111ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def test_missing_file(self):
1121ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with self.assertRaises(FileNotFoundError):
1131ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            imghdr.what('missing')
1141ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
1151ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def test_closed_file(self):
1161ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        stream = open(self.testfile, 'rb')
1171ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        stream.close()
1181ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with self.assertRaises(ValueError) as cm:
1191ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            imghdr.what(stream)
1201ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        stream = io.BytesIO(self.testdata)
1211ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        stream.close()
1221ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with self.assertRaises(ValueError) as cm:
1231ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            imghdr.what(stream)
1241ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
1251ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def test_unseekable(self):
1261ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with open(TESTFN, 'wb') as stream:
1271ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            stream.write(self.testdata)
1281ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with UnseekableIO(TESTFN, 'rb') as stream:
1291ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            with self.assertRaises(io.UnsupportedOperation):
1301ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                imghdr.what(stream)
1311ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
1321ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    def test_output_stream(self):
1331ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka        with open(TESTFN, 'wb') as stream:
1341ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            stream.write(self.testdata)
1351ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            stream.seek(0)
1361ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka            with self.assertRaises(OSError) as cm:
1371ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka                imghdr.what(stream)
1381ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka
1391ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchakaif __name__ == '__main__':
1401ac00950b28e91fc35fed6445722ade92732648eSerhiy Storchaka    unittest.main()
141