From 62863a0b655451d8ae1657c118d6c3f62e641ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 18 Mar 2025 12:53:55 +0100 Subject: [PATCH 1/8] fix `test_mimetypes.test_guess_type_conflicting_with_mimetypes` Using `run_python_until_end()` ignores `setUpModule()`. In particular, mocking `mimetypes.knownfiles` has no effect for the CLI tests and leads to issues on platforms defining non-standard MIME types such as macOS or openSUSE. --- Lib/mimetypes.py | 10 ++++++---- Lib/test/test_mimetypes.py | 25 +++++++++++++++++-------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 6b94fe3c4df756..85988ea00730e8 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -669,7 +669,7 @@ def _default_mime_types(): _default_mime_types() -def _main(): +def _main(args=None): """Run the mimetypes command-line interface.""" import sys from argparse import ArgumentParser @@ -686,7 +686,7 @@ def _main(): help='additionally search for common but non-standard types' ) parser.add_argument('type', nargs='+', help='a type to search') - args = parser.parse_args() + args = parser.parse_args(args) if args.extension: for gtype in args.type: @@ -694,14 +694,16 @@ def _main(): if guess: print(guess) else: - sys.exit(f"error: unknown type {gtype}") + print(f"error: unknown type {gtype}", file=sys.stderr) + sys.exit(1) else: for gtype in args.type: guess, encoding = guess_type(gtype, not args.lenient) if guess: print('type:', guess, 'encoding:', encoding) else: - sys.exit(f"error: media type unknown for {gtype}") + print(f"error: media type unknown for {gtype}", file=sys.stderr) + sys.exit(1) if __name__ == '__main__': diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index b5d1f50099e16a..99f6cbf7a3ca72 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -1,7 +1,9 @@ +import contextlib import io import mimetypes import os import sys +import tempfile import unittest.mock from os import linesep @@ -392,9 +394,19 @@ def test__all__(self): class MimetypesCliTestCase(unittest.TestCase): - def mimetypes_cmd(cls, *args, **kwargs): - result, _ = run_python_until_end('-m', 'mimetypes', *args) - return result.rc, result.out.decode(), result.err.decode() + def mimetypes_cmd(self, *args): + # We cannot use run_python_until_end() as the latter would not + # call setUpModule() which unsets mimetypes.knowfiles. Instead, + # we need to directly call the main() function in order to avoid + # re-initializing the database. + rc, out, err = 0, io.StringIO(), io.StringIO() + with contextlib.redirect_stdout(out), contextlib.redirect_stderr(err): + try: + mimetypes._main(args) + except SystemExit as exc: + self.assertIsInstance(exc.code, int) + rc = exc.code + return rc, out.getvalue(), err.getvalue() def test_help_option(self): retcode, out, err = self.mimetypes_cmd('-h') @@ -430,15 +442,12 @@ def test_guess_type(self): self.assertEqual(out, f'type: image/webp encoding: None{linesep}') self.assertEqual(err, '') - @unittest.skipIf( - sys.platform == 'darwin', - 'macOS lists common_types in mime.types thus making them always known' - ) - def test_guess_type_conflicting_with_mimetypes(self): + def test_z_guess_type_conflicting_with_mimetypes(self): retcode, out, err = self.mimetypes_cmd('foo.pic') self.assertEqual(retcode, 1) self.assertEqual(out, '') self.assertEqual(err, f'error: media type unknown for foo.pic{linesep}') + if __name__ == "__main__": unittest.main() From 7be23f021cd06c8e8cdefdcfa11dd1d7f7fac39f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 18 Mar 2025 13:33:28 +0100 Subject: [PATCH 2/8] remove checks for linesep --- Lib/test/test_mimetypes.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 99f6cbf7a3ca72..ca6672e4b5ca27 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -5,7 +5,6 @@ import sys import tempfile import unittest.mock -from os import linesep from test import support from test.support import os_helper @@ -423,30 +422,30 @@ def test_invalid_option(self): def test_guess_extension(self): retcode, out, err = self.mimetypes_cmd('-l', '-e', 'image/jpg') self.assertEqual(retcode, 0) - self.assertEqual(out, f'.jpg{linesep}') + self.assertEqual(out, '.jpg\n') self.assertEqual(err, '') retcode, out, err = self.mimetypes_cmd('-e', 'image/jpg') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, f'error: unknown type image/jpg{linesep}') + self.assertEqual(err, 'error: unknown type image/jpg\n') retcode, out, err = self.mimetypes_cmd('-e', 'image/jpeg') self.assertEqual(retcode, 0) - self.assertEqual(out, f'.jpg{linesep}') + self.assertEqual(out, '.jpg\n') self.assertEqual(err, '') def test_guess_type(self): retcode, out, err = self.mimetypes_cmd('-l', 'foo.webp') self.assertEqual(retcode, 0) - self.assertEqual(out, f'type: image/webp encoding: None{linesep}') + self.assertEqual(out, 'type: image/webp encoding: None\n') self.assertEqual(err, '') def test_z_guess_type_conflicting_with_mimetypes(self): retcode, out, err = self.mimetypes_cmd('foo.pic') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, f'error: media type unknown for foo.pic{linesep}') + self.assertEqual(err, 'error: media type unknown for foo.pic\n') if __name__ == "__main__": From 01e89c35d8604a34ad9d962fad93e1b7b6757bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Wed, 26 Mar 2025 10:28:19 +0100 Subject: [PATCH 3/8] use `parser.exit()` instead of print + sys.exit() --- Lib/mimetypes.py | 8 ++++---- Lib/test/test_mimetypes.py | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 85988ea00730e8..44dde5ec91ffe5 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -694,16 +694,16 @@ def _main(args=None): if guess: print(guess) else: - print(f"error: unknown type {gtype}", file=sys.stderr) - sys.exit(1) + # do not use parser.error() as it prints a help message + parser.exit(1, f"error: unknown type {gtype}\n") else: for gtype in args.type: guess, encoding = guess_type(gtype, not args.lenient) if guess: print('type:', guess, 'encoding:', encoding) else: - print(f"error: media type unknown for {gtype}", file=sys.stderr) - sys.exit(1) + # do not use parser.error() as it prints a help message + parser.exit(1, f"error: media type unknown for {gtype}\n") if __name__ == '__main__': diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index ca6672e4b5ca27..aa44acf0d00a2d 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -5,11 +5,11 @@ import sys import tempfile import unittest.mock - +from os import linesep +from platform import win32_edition from test import support from test.support import os_helper from test.support.script_helper import run_python_until_end -from platform import win32_edition try: import _winapi @@ -422,30 +422,30 @@ def test_invalid_option(self): def test_guess_extension(self): retcode, out, err = self.mimetypes_cmd('-l', '-e', 'image/jpg') self.assertEqual(retcode, 0) - self.assertEqual(out, '.jpg\n') + self.assertEqual(out, f'.jpg{linesep}') self.assertEqual(err, '') retcode, out, err = self.mimetypes_cmd('-e', 'image/jpg') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, 'error: unknown type image/jpg\n') + self.assertEqual(err, f'error: unknown type image/jpg{linesep}') retcode, out, err = self.mimetypes_cmd('-e', 'image/jpeg') self.assertEqual(retcode, 0) - self.assertEqual(out, '.jpg\n') + self.assertEqual(out, f'.jpg{linesep}') self.assertEqual(err, '') def test_guess_type(self): retcode, out, err = self.mimetypes_cmd('-l', 'foo.webp') self.assertEqual(retcode, 0) - self.assertEqual(out, 'type: image/webp encoding: None\n') + self.assertEqual(out, f'type: image/webp encoding: None{linesep}') self.assertEqual(err, '') - def test_z_guess_type_conflicting_with_mimetypes(self): + def test_guess_type_conflicting_with_mimetypes(self): retcode, out, err = self.mimetypes_cmd('foo.pic') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, 'error: media type unknown for foo.pic\n') + self.assertEqual(err, f'error: media type unknown for foo.pic{linesep}') if __name__ == "__main__": From 1d29b5d82395b6c05265aec8afd2d92e277b1c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 28 Mar 2025 15:21:01 +0100 Subject: [PATCH 4/8] fixup --- Lib/test/test_mimetypes.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index aa44acf0d00a2d..9b7705a5a3411f 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -5,7 +5,6 @@ import sys import tempfile import unittest.mock -from os import linesep from platform import win32_edition from test import support from test.support import os_helper @@ -422,30 +421,30 @@ def test_invalid_option(self): def test_guess_extension(self): retcode, out, err = self.mimetypes_cmd('-l', '-e', 'image/jpg') self.assertEqual(retcode, 0) - self.assertEqual(out, f'.jpg{linesep}') + self.assertEqual(out, '.jpg\n') self.assertEqual(err, '') retcode, out, err = self.mimetypes_cmd('-e', 'image/jpg') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, f'error: unknown type image/jpg{linesep}') + self.assertEqual(err, 'error: unknown type image/jpg\n') retcode, out, err = self.mimetypes_cmd('-e', 'image/jpeg') self.assertEqual(retcode, 0) - self.assertEqual(out, f'.jpg{linesep}') + self.assertEqual(out, '.jpg\n') self.assertEqual(err, '') def test_guess_type(self): retcode, out, err = self.mimetypes_cmd('-l', 'foo.webp') self.assertEqual(retcode, 0) - self.assertEqual(out, f'type: image/webp encoding: None{linesep}') + self.assertEqual(out, 'type: image/webp encoding: None\n') self.assertEqual(err, '') def test_guess_type_conflicting_with_mimetypes(self): retcode, out, err = self.mimetypes_cmd('foo.pic') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, f'error: media type unknown for foo.pic{linesep}') + self.assertEqual(err, 'error: media type unknown for foo.pic\n') if __name__ == "__main__": From eeb563524299af1b983b44ad0516a5bf4b9ea1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 30 Mar 2025 11:23:25 +0200 Subject: [PATCH 5/8] Update Lib/test/test_mimetypes.py --- Lib/test/test_mimetypes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 9b7705a5a3411f..7f782b42d97920 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -3,7 +3,6 @@ import mimetypes import os import sys -import tempfile import unittest.mock from platform import win32_edition from test import support From d9d136e091a329e20033499312b28b08f82eef59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 8 Apr 2025 10:29:57 +0200 Subject: [PATCH 6/8] use Hugo's approach for testing `mimetypes` --- Lib/mimetypes.py | 27 +++++----- Lib/test/test_mimetypes.py | 101 +++++++++++++++++-------------------- 2 files changed, 61 insertions(+), 67 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 44dde5ec91ffe5..67660e4f0368ce 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -669,9 +669,7 @@ def _default_mime_types(): _default_mime_types() -def _main(args=None): - """Run the mimetypes command-line interface.""" - import sys +def _parse_args(args): from argparse import ArgumentParser parser = ArgumentParser(description='map filename extensions to MIME types') @@ -687,24 +685,29 @@ def _main(args=None): ) parser.add_argument('type', nargs='+', help='a type to search') args = parser.parse_args(args) + return args, parser.format_help() + + +def _main(args=None): + """Run the mimetypes command-line interface and return a text to print.""" + import sys + + args, help_text = _parse_args(args) if args.extension: for gtype in args.type: guess = guess_extension(gtype, not args.lenient) if guess: - print(guess) - else: - # do not use parser.error() as it prints a help message - parser.exit(1, f"error: unknown type {gtype}\n") + return str(guess) + sys.exit(f"error: unknown type {gtype}") else: for gtype in args.type: guess, encoding = guess_type(gtype, not args.lenient) if guess: - print('type:', guess, 'encoding:', encoding) - else: - # do not use parser.error() as it prints a help message - parser.exit(1, f"error: media type unknown for {gtype}\n") + return f"type: {guess} encoding: {encoding}" + sys.exit(f"error: media type unknown for {gtype}") + return parser.format_help() if __name__ == '__main__': - _main() + print(_main()) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 7f782b42d97920..b05c212a2a6b6b 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -2,6 +2,7 @@ import io import mimetypes import os +import shlex import sys import unittest.mock from platform import win32_edition @@ -389,61 +390,51 @@ def test__all__(self): support.check__all__(self, mimetypes) -class MimetypesCliTestCase(unittest.TestCase): - - def mimetypes_cmd(self, *args): - # We cannot use run_python_until_end() as the latter would not - # call setUpModule() which unsets mimetypes.knowfiles. Instead, - # we need to directly call the main() function in order to avoid - # re-initializing the database. - rc, out, err = 0, io.StringIO(), io.StringIO() - with contextlib.redirect_stdout(out), contextlib.redirect_stderr(err): - try: - mimetypes._main(args) - except SystemExit as exc: - self.assertIsInstance(exc.code, int) - rc = exc.code - return rc, out.getvalue(), err.getvalue() - - def test_help_option(self): - retcode, out, err = self.mimetypes_cmd('-h') - self.assertEqual(retcode, 0) - self.assertStartsWith(out, 'usage: ') - self.assertEqual(err, '') - - def test_invalid_option(self): - retcode, out, err = self.mimetypes_cmd('--invalid') - self.assertEqual(retcode, 2) - self.assertEqual(out, '') - self.assertStartsWith(err, 'usage: ') - - def test_guess_extension(self): - retcode, out, err = self.mimetypes_cmd('-l', '-e', 'image/jpg') - self.assertEqual(retcode, 0) - self.assertEqual(out, '.jpg\n') - self.assertEqual(err, '') - - retcode, out, err = self.mimetypes_cmd('-e', 'image/jpg') - self.assertEqual(retcode, 1) - self.assertEqual(out, '') - self.assertEqual(err, 'error: unknown type image/jpg\n') - - retcode, out, err = self.mimetypes_cmd('-e', 'image/jpeg') - self.assertEqual(retcode, 0) - self.assertEqual(out, '.jpg\n') - self.assertEqual(err, '') - - def test_guess_type(self): - retcode, out, err = self.mimetypes_cmd('-l', 'foo.webp') - self.assertEqual(retcode, 0) - self.assertEqual(out, 'type: image/webp encoding: None\n') - self.assertEqual(err, '') - - def test_guess_type_conflicting_with_mimetypes(self): - retcode, out, err = self.mimetypes_cmd('foo.pic') - self.assertEqual(retcode, 1) - self.assertEqual(out, '') - self.assertEqual(err, 'error: media type unknown for foo.pic\n') +class CommandLineTest(unittest.TestCase): + def test_parse_args(self): + args, help_text = mimetypes._parse_args("-h") + self.assertTrue(help_text.startswith("usage: ")) + + args, help_text = mimetypes._parse_args("--invalid") + self.assertTrue(help_text.startswith("usage: ")) + + args, _ = mimetypes._parse_args(shlex.split("-l -e image/jpg")) + self.assertTrue(args.extension) + self.assertTrue(args.lenient) + self.assertEqual(args.type, ["image/jpg"]) + + args, _ = mimetypes._parse_args(shlex.split("-e image/jpg")) + self.assertTrue(args.extension) + self.assertFalse(args.lenient) + self.assertEqual(args.type, ["image/jpg"]) + + args, _ = mimetypes._parse_args(shlex.split("-l foo.webp")) + self.assertFalse(args.extension) + self.assertTrue(args.lenient) + self.assertEqual(args.type, ["foo.webp"]) + + args, _ = mimetypes._parse_args(shlex.split("foo.pic")) + self.assertFalse(args.extension) + self.assertFalse(args.lenient) + self.assertEqual(args.type, ["foo.pic"]) + + + def test_invocation(self): + for command, expected in [ + ("-l -e image/jpg", ".jpg"), + ("-e image/jpeg", ".jpg"), + ("-l foo.webp", "type: image/webp encoding: None"), + ]: + self.assertEqual(mimetypes._main(shlex.split(command)), expected) + + + def test_invocation_error(self): + for command, expected in [ + ("-e image/jpg", "error: unknown type image/jpg"), + ("foo.pic", "error: media type unknown for foo.pic"), + ]: + with self.assertRaisesRegex(SystemExit, expected): + mimetypes._main(shlex.split(command)) if __name__ == "__main__": From b0c29fa202568887c05b1d7c243d3f0ae9b5513a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 8 Apr 2025 10:37:41 +0200 Subject: [PATCH 7/8] Update Lib/test/test_mimetypes.py --- Lib/test/test_mimetypes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index b05c212a2a6b6b..2da1c13800e875 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -1,4 +1,3 @@ -import contextlib import io import mimetypes import os From 56bbd953f3ef6148048364ee7c5e8c126f384786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 8 Apr 2025 10:41:54 +0200 Subject: [PATCH 8/8] [empty commit to trigger CI] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy