From 494fba8d9a424bdc21b83bdae23dc03cad8f05c9 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Thu, 24 Mar 2022 20:10:32 +0300 Subject: [PATCH 01/56] Make mimetypes CLI tool public --- Doc/library/mimetypes.rst | 33 ++++++++++++++++++++++++ Lib/mimetypes.py | 54 ++++++++++----------------------------- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index f610032acbe417..63d29a1d0eac50 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -272,3 +272,36 @@ than one MIME-type database; it provides an interface similar to the one of the types, else to the list of non-standard types. .. versionadded:: 3.2 + + +.. mimetypes-cli: + +Command-Line Usage +------------------ + +The :mod:`mimetypes` module can be executed as a script from the command line. +It is as simple as: + +.. code-block:: sh + + python -m mimetypes [-e] [-l] type [type ...] + +The following options are accepted: + +.. program:: filecmp + +.. cmdoption:: -h, --help + + Show the help message and exit. + +.. cmdoption:: -e, --extension + + Guess extension instead of type. + +.. cmdoption:: -l, --lenient + + Additionally search of some common, but non-standard types. + +The script scans the internal database and converts either file extensions to +MIME types or vice versa depending on whether ``--extension`` option is +specified. diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 1aa32467e278a3..fc10b99272a433 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -596,51 +596,25 @@ def _default_mime_types(): _default_mime_types() -def _main(): - import getopt - - USAGE = """\ -Usage: mimetypes.py [options] type - -Options: - --help / -h -- print this message and exit - --lenient / -l -- additionally search of some common, but non-standard - types. - --extension / -e -- guess extension instead of type - -More than one type argument may be given. -""" - - def usage(code, msg=''): - print(USAGE) - if msg: print(msg) - sys.exit(code) - - try: - opts, args = getopt.getopt(sys.argv[1:], 'hle', - ['help', 'lenient', 'extension']) - except getopt.error as msg: - usage(1, msg) - - strict = 1 - extension = 0 - for opt, arg in opts: - if opt in ('-h', '--help'): - usage(0) - elif opt in ('-l', '--lenient'): - strict = 0 - elif opt in ('-e', '--extension'): - extension = 1 - for gtype in args: - if extension: - guess = guess_extension(gtype, strict) +def _cli(): + from argparse import ArgumentParser + parser = ArgumentParser(description='compare directories and files') + parser.add_argument('-e', '--extension', action='store_true', + help='guess extension instead of type') + parser.add_argument('-l', '--lenient', action='store_true', + help='search also for common but non-standard types') + parser.add_argument('type', nargs='+', help='type to search') + arguments = parser.parse_args() + for gtype in arguments.type: + if arguments.extension: + guess = guess_extension(gtype, not arguments.lenient) if not guess: print("I don't know anything about type", gtype) else: print(guess) else: - guess, encoding = guess_type(gtype, strict) + guess, encoding = guess_type(gtype, not arguments.lenient) if not guess: print("I don't know anything about type", gtype) else: print('type:', guess, 'encoding:', encoding) if __name__ == '__main__': - _main() + _cli() From 5fdd90992aecbe78a6e597bf2259492cff330d08 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Mon, 23 May 2022 11:53:43 +0300 Subject: [PATCH 02/56] Add NEWS --- .../next/Library/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst diff --git a/Misc/NEWS.d/next/Library/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst b/Misc/NEWS.d/next/Library/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst new file mode 100644 index 00000000000000..3350e57f70f309 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst @@ -0,0 +1 @@ +Added *Command-Line Usage* section for :mod:`mimetypes`. From 1d778e2c030b397ea35786dc0c5bb31805be717d Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Mon, 23 May 2022 12:54:57 +0300 Subject: [PATCH 03/56] No other module names the entry point _cli --- Lib/mimetypes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index c5a0d92c5d0e35..ce68a452a87b94 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -598,7 +598,7 @@ def _default_mime_types(): _default_mime_types() -def _cli(): +def _main(): from argparse import ArgumentParser parser = ArgumentParser(description='compare directories and files') parser.add_argument('-e', '--extension', action='store_true', @@ -619,4 +619,4 @@ def _cli(): if __name__ == '__main__': - _cli() + _main() From d67704f4291ba335187b04ee4b112914aa388d53 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Mon, 23 May 2022 16:29:29 +0300 Subject: [PATCH 04/56] Adjust tests (capitalization of "Usage:" changed) --- Lib/test/test_mimetypes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index d64aee71fc48b1..ae6b054f38ce1f 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -297,7 +297,7 @@ def test_help_option(self): with self.assertRaises(SystemExit) as cm: mimetypes._main() - self.assertIn("Usage: mimetypes.py", output.getvalue()) + self.assertIn("usage: mimetypes.py", output.getvalue()) self.assertEqual(cm.exception.code, 0) def test_invalid_option(self): @@ -306,7 +306,7 @@ def test_invalid_option(self): with self.assertRaises(SystemExit) as cm: mimetypes._main() - self.assertIn("Usage: mimetypes.py", output.getvalue()) + self.assertIn("usage: mimetypes.py", output.getvalue()) self.assertEqual(cm.exception.code, 1) def test_guess_extension(self): From 55df248ad591c619b647dd34313d1a8d578d0beb Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Mon, 23 May 2022 18:25:01 +0300 Subject: [PATCH 05/56] For CLI tests, make proper script invocations with proper checks --- Lib/test/test_mimetypes.py | 72 ++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index ae6b054f38ce1f..68be10bc829d7d 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -6,6 +6,7 @@ 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: @@ -285,50 +286,53 @@ def test__all__(self): class MimetypesCliTestCase(unittest.TestCase): - def mimetypes_cmd(self, *args, **kwargs): - support.patch(self, sys, "argv", [sys.executable, *args]) - with support.captured_stdout() as output: - mimetypes._main() - return output.getvalue().strip() + @classmethod + def to_string(cls, stream): + return stream.decode('ascii').strip() - def test_help_option(self): - support.patch(self, sys, "argv", [sys.executable, "-h"]) - with support.captured_stdout() as output: - with self.assertRaises(SystemExit) as cm: - mimetypes._main() + @classmethod + def mimetypes_cmd(cls, *args, **kwargs): + result, _ = run_python_until_end('-m', 'mimetypes', *args) + return result.rc, cls.to_string(result.out), cls.to_string(result.err) - self.assertIn("usage: mimetypes.py", output.getvalue()) - self.assertEqual(cm.exception.code, 0) + def test_help_option(self): + retcode, out, err = self.mimetypes_cmd('-h') + self.assertEqual(retcode, 0) + self.assertIn('usage: mimetypes.py', out) + self.assertEqual(err, '') def test_invalid_option(self): - support.patch(self, sys, "argv", [sys.executable, "--invalid"]) - with support.captured_stdout() as output: - with self.assertRaises(SystemExit) as cm: - mimetypes._main() - - self.assertIn("usage: mimetypes.py", output.getvalue()) - self.assertEqual(cm.exception.code, 1) + retcode, out, err = self.mimetypes_cmd('--invalid') + self.assertEqual(retcode, 2) + self.assertEqual(out, '') + self.assertIn('usage: mimetypes.py', err) def test_guess_extension(self): - eq = self.assertEqual + retcode, out, err = self.mimetypes_cmd('-l', '-e', 'image/jpg') + self.assertEqual(retcode, 0) + self.assertEqual(out, '.jpg') + self.assertEqual(err, '') - extension = self.mimetypes_cmd("-l", "-e", "image/jpg") - eq(extension, ".jpg") + retcode, out, err = self.mimetypes_cmd('-e', 'image/jpg') + self.assertEqual(retcode, 0) + self.assertEqual(out, "I don't know anything about type image/jpg") + self.assertEqual(err, '') - extension = self.mimetypes_cmd("-e", "image/jpg") - eq(extension, "I don't know anything about type image/jpg") - - extension = self.mimetypes_cmd("-e", "image/jpeg") - eq(extension, ".jpg") + retcode, out, err = self.mimetypes_cmd("-e", "image/jpeg") + self.assertEqual(retcode, 0) + self.assertEqual(out, '.jpg') + self.assertEqual(err, '') def test_guess_type(self): - eq = self.assertEqual - - type_info = self.mimetypes_cmd("-l", "foo.pic") - eq(type_info, "type: image/pict encoding: None") - - type_info = self.mimetypes_cmd("foo.pic") - eq(type_info, "I don't know anything about type foo.pic") + retcode, out, err = self.mimetypes_cmd('-l', 'foo.pic') + self.assertEqual(retcode, 0) + self.assertEqual(out, "type: image/pict encoding: None") + self.assertEqual(err, '') + + retcode, out, err = self.mimetypes_cmd('foo.pic') + self.assertEqual(retcode, 0) + self.assertEqual(out, "I don't know anything about type foo.pic") + self.assertEqual(err, '') if __name__ == "__main__": unittest.main() From b065ed863cee919cdff4eafecb5af851cc2f514a Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 May 2022 13:01:41 +0300 Subject: [PATCH 06/56] Address @AA-Turner's review --- Lib/mimetypes.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index ce68a452a87b94..495db95163db74 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -600,7 +600,7 @@ def _default_mime_types(): def _main(): from argparse import ArgumentParser - parser = ArgumentParser(description='compare directories and files') + parser = ArgumentParser(description='map filename extensions to MIME types') parser.add_argument('-e', '--extension', action='store_true', help='guess extension instead of type') parser.add_argument('-l', '--lenient', action='store_true', @@ -610,12 +610,17 @@ def _main(): for gtype in arguments.type: if arguments.extension: guess = guess_extension(gtype, not arguments.lenient) - if not guess: print("I don't know anything about type", gtype) - else: print(guess) + if guess: + print(guess) + else: + print("I don't know anything about type", gtype) + else: guess, encoding = guess_type(gtype, not arguments.lenient) - if not guess: print("I don't know anything about type", gtype) - else: print('type:', guess, 'encoding:', encoding) + if guess: + print('type:', guess, 'encoding:', encoding) + else: + print("I don't know anything about type", gtype) if __name__ == '__main__': From e7db03d7482974966288bdabc6f7ed9fe7a54344 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 May 2022 13:08:39 +0300 Subject: [PATCH 07/56] Move a constant check outside of a loop --- Lib/mimetypes.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 495db95163db74..47fa01e8485034 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -607,15 +607,16 @@ def _main(): help='search also for common but non-standard types') parser.add_argument('type', nargs='+', help='type to search') arguments = parser.parse_args() - for gtype in arguments.type: - if arguments.extension: + + if arguments.extension: + for gtype in arguments.type: guess = guess_extension(gtype, not arguments.lenient) if guess: print(guess) else: print("I don't know anything about type", gtype) - - else: + else: + for gtype in arguments.type: guess, encoding = guess_type(gtype, not arguments.lenient) if guess: print('type:', guess, 'encoding:', encoding) From 6a1c96a9e8c3a265e5be4491fb0dc20b4bb9899f Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Thu, 26 May 2022 08:16:15 +0300 Subject: [PATCH 08/56] Allow .pic MIME type be image/x-pict --- Lib/test/test_mimetypes.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 68be10bc829d7d..6dc9c9cd87ec1a 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -326,7 +326,10 @@ def test_guess_extension(self): def test_guess_type(self): retcode, out, err = self.mimetypes_cmd('-l', 'foo.pic') self.assertEqual(retcode, 0) - self.assertEqual(out, "type: image/pict encoding: None") + self.assertIn(out, [ + 'type: image/pict encoding: None', + 'type: image/x-pict encoding: None' + ]) self.assertEqual(err, '') retcode, out, err = self.mimetypes_cmd('foo.pic') From 010354d52abef1b33aa361cbc1f7fa40d18fc9e1 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Thu, 26 May 2022 09:47:13 +0300 Subject: [PATCH 09/56] Follow PEP 8 more --- Lib/mimetypes.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 47fa01e8485034..17feffb42aacf4 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -601,11 +601,17 @@ def _default_mime_types(): def _main(): from argparse import ArgumentParser parser = ArgumentParser(description='map filename extensions to MIME types') - parser.add_argument('-e', '--extension', action='store_true', - help='guess extension instead of type') - parser.add_argument('-l', '--lenient', action='store_true', - help='search also for common but non-standard types') - parser.add_argument('type', nargs='+', help='type to search') + parser.add_argument( + '-e', '--extension', + action='store_true', + help='guess extension instead of type' + ) + parser.add_argument( + '-l', '--lenient', + action='store_true', + help='additianally search for common but non-standard types' + ) + parser.add_argument('type', nargs='+', help='a type to search') arguments = parser.parse_args() if arguments.extension: From 3368be443189f28da4da43512a3bfe3287f33e72 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 18:59:41 +0300 Subject: [PATCH 10/56] Change forgotten quotation marks --- Lib/test/test_mimetypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 6dc9c9cd87ec1a..0bc78dd984217c 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -318,7 +318,7 @@ def test_guess_extension(self): self.assertEqual(out, "I don't know anything about type image/jpg") self.assertEqual(err, '') - retcode, out, err = self.mimetypes_cmd("-e", "image/jpeg") + retcode, out, err = self.mimetypes_cmd('-e', 'image/jpeg') self.assertEqual(retcode, 0) self.assertEqual(out, '.jpg') self.assertEqual(err, '') From 26bec360d282e0cb783d69235486d424c56eb575 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 19:03:19 +0300 Subject: [PATCH 11/56] Temporarily rollback everything but tests --- Lib/mimetypes.py | 74 ++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 17feffb42aacf4..1aa32467e278a3 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -517,7 +517,6 @@ def _default_mime_types(): '.aiff' : 'audio/x-aiff', '.ra' : 'audio/x-pn-realaudio', '.wav' : 'audio/x-wav', - '.avif' : 'image/avif', '.bmp' : 'image/bmp', '.gif' : 'image/gif', '.ief' : 'image/ief', @@ -590,7 +589,6 @@ def _default_mime_types(): '.pict': 'image/pict', '.pct' : 'image/pict', '.pic' : 'image/pict', - '.webp': 'image/webp', '.xul' : 'text/xul', } @@ -599,35 +597,49 @@ def _default_mime_types(): def _main(): - from argparse import ArgumentParser - parser = ArgumentParser(description='map filename extensions to MIME types') - parser.add_argument( - '-e', '--extension', - action='store_true', - help='guess extension instead of type' - ) - parser.add_argument( - '-l', '--lenient', - action='store_true', - help='additianally search for common but non-standard types' - ) - parser.add_argument('type', nargs='+', help='a type to search') - arguments = parser.parse_args() - - if arguments.extension: - for gtype in arguments.type: - guess = guess_extension(gtype, not arguments.lenient) - if guess: - print(guess) - else: - print("I don't know anything about type", gtype) - else: - for gtype in arguments.type: - guess, encoding = guess_type(gtype, not arguments.lenient) - if guess: - print('type:', guess, 'encoding:', encoding) - else: - print("I don't know anything about type", gtype) + import getopt + + USAGE = """\ +Usage: mimetypes.py [options] type + +Options: + --help / -h -- print this message and exit + --lenient / -l -- additionally search of some common, but non-standard + types. + --extension / -e -- guess extension instead of type + +More than one type argument may be given. +""" + + def usage(code, msg=''): + print(USAGE) + if msg: print(msg) + sys.exit(code) + + try: + opts, args = getopt.getopt(sys.argv[1:], 'hle', + ['help', 'lenient', 'extension']) + except getopt.error as msg: + usage(1, msg) + + strict = 1 + extension = 0 + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-l', '--lenient'): + strict = 0 + elif opt in ('-e', '--extension'): + extension = 1 + for gtype in args: + if extension: + guess = guess_extension(gtype, strict) + if not guess: print("I don't know anything about type", gtype) + else: print(guess) + else: + guess, encoding = guess_type(gtype, strict) + if not guess: print("I don't know anything about type", gtype) + else: print('type:', guess, 'encoding:', encoding) if __name__ == '__main__': From f1d4364a0cef130c2a7c97621e526f9e698cfcae Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 19:18:45 +0300 Subject: [PATCH 12/56] Revert "Temporarily rollback everything but tests" This reverts commit 26bec360d282e0cb783d69235486d424c56eb575. --- Lib/mimetypes.py | 74 ++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 43 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 1aa32467e278a3..17feffb42aacf4 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -517,6 +517,7 @@ def _default_mime_types(): '.aiff' : 'audio/x-aiff', '.ra' : 'audio/x-pn-realaudio', '.wav' : 'audio/x-wav', + '.avif' : 'image/avif', '.bmp' : 'image/bmp', '.gif' : 'image/gif', '.ief' : 'image/ief', @@ -589,6 +590,7 @@ def _default_mime_types(): '.pict': 'image/pict', '.pct' : 'image/pict', '.pic' : 'image/pict', + '.webp': 'image/webp', '.xul' : 'text/xul', } @@ -597,49 +599,35 @@ def _default_mime_types(): def _main(): - import getopt - - USAGE = """\ -Usage: mimetypes.py [options] type - -Options: - --help / -h -- print this message and exit - --lenient / -l -- additionally search of some common, but non-standard - types. - --extension / -e -- guess extension instead of type - -More than one type argument may be given. -""" - - def usage(code, msg=''): - print(USAGE) - if msg: print(msg) - sys.exit(code) - - try: - opts, args = getopt.getopt(sys.argv[1:], 'hle', - ['help', 'lenient', 'extension']) - except getopt.error as msg: - usage(1, msg) - - strict = 1 - extension = 0 - for opt, arg in opts: - if opt in ('-h', '--help'): - usage(0) - elif opt in ('-l', '--lenient'): - strict = 0 - elif opt in ('-e', '--extension'): - extension = 1 - for gtype in args: - if extension: - guess = guess_extension(gtype, strict) - if not guess: print("I don't know anything about type", gtype) - else: print(guess) - else: - guess, encoding = guess_type(gtype, strict) - if not guess: print("I don't know anything about type", gtype) - else: print('type:', guess, 'encoding:', encoding) + from argparse import ArgumentParser + parser = ArgumentParser(description='map filename extensions to MIME types') + parser.add_argument( + '-e', '--extension', + action='store_true', + help='guess extension instead of type' + ) + parser.add_argument( + '-l', '--lenient', + action='store_true', + help='additianally search for common but non-standard types' + ) + parser.add_argument('type', nargs='+', help='a type to search') + arguments = parser.parse_args() + + if arguments.extension: + for gtype in arguments.type: + guess = guess_extension(gtype, not arguments.lenient) + if guess: + print(guess) + else: + print("I don't know anything about type", gtype) + else: + for gtype in arguments.type: + guess, encoding = guess_type(gtype, not arguments.lenient) + if guess: + print('type:', guess, 'encoding:', encoding) + else: + print("I don't know anything about type", gtype) if __name__ == '__main__': From 5e1de1777b38c05b0b6774fe723a36bb98b19420 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 19:27:39 +0300 Subject: [PATCH 13/56] Add comments about assertIn() --- Lib/test/test_mimetypes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 0bc78dd984217c..6c457dabd839cf 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -327,7 +327,9 @@ def test_guess_type(self): retcode, out, err = self.mimetypes_cmd('-l', 'foo.pic') self.assertEqual(retcode, 0) self.assertIn(out, [ + # Returned from the defaults when mime.types is missing 'type: image/pict encoding: None', + # May be returned when mime.types is present 'type: image/x-pict encoding: None' ]) self.assertEqual(err, '') From 48f1746ef25638b92e5e2037414b460c90e4867f Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 19:42:00 +0300 Subject: [PATCH 14/56] Normalize error codes too --- Lib/mimetypes.py | 6 +++--- Lib/test/test_mimetypes.py | 4 ++-- .../Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 17feffb42aacf4..fa0db58a0d116b 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -24,7 +24,7 @@ """ import os -import sys +from sys import exit import posixpath import urllib.parse @@ -620,14 +620,14 @@ def _main(): if guess: print(guess) else: - print("I don't know anything about type", gtype) + exit("I don't know anything about type", gtype) else: for gtype in arguments.type: guess, encoding = guess_type(gtype, not arguments.lenient) if guess: print('type:', guess, 'encoding:', encoding) else: - print("I don't know anything about type", gtype) + exit("I don't know anything about type", gtype) if __name__ == '__main__': diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 6c457dabd839cf..f844cad75b2191 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -314,7 +314,7 @@ def test_guess_extension(self): self.assertEqual(err, '') retcode, out, err = self.mimetypes_cmd('-e', 'image/jpg') - self.assertEqual(retcode, 0) + self.assertEqual(retcode, 1) self.assertEqual(out, "I don't know anything about type image/jpg") self.assertEqual(err, '') @@ -335,7 +335,7 @@ def test_guess_type(self): self.assertEqual(err, '') retcode, out, err = self.mimetypes_cmd('foo.pic') - self.assertEqual(retcode, 0) + self.assertEqual(retcode, 1) self.assertEqual(out, "I don't know anything about type foo.pic") self.assertEqual(err, '') diff --git a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst new file mode 100644 index 00000000000000..055336abe9627e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst @@ -0,0 +1,2 @@ +Command-line :mod:`mimetypes` started to return 1 instead of 0 for +abruptions and 2 instead of 1 for incorrect command line parameters. From 11b067dc379918305e3babf925bddbbe69a69a8a Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 20:06:23 +0300 Subject: [PATCH 15/56] `from sys import exit` clashes with the exit builtin --- Lib/mimetypes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index fa0db58a0d116b..dcb037e742f25f 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -24,7 +24,7 @@ """ import os -from sys import exit +import sys import posixpath import urllib.parse @@ -620,14 +620,14 @@ def _main(): if guess: print(guess) else: - exit("I don't know anything about type", gtype) + sys.exit("I don't know anything about type", gtype) else: for gtype in arguments.type: guess, encoding = guess_type(gtype, not arguments.lenient) if guess: print('type:', guess, 'encoding:', encoding) else: - exit("I don't know anything about type", gtype) + sys.exit("I don't know anything about type", gtype) if __name__ == '__main__': From 5589f7a906cf3b0835ec6f4d76e36e314c57da14 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 20:07:58 +0300 Subject: [PATCH 16/56] Use f-strings for sys.exit() --- Lib/mimetypes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index dcb037e742f25f..f5c75f9dae4ada 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -620,14 +620,14 @@ def _main(): if guess: print(guess) else: - sys.exit("I don't know anything about type", gtype) + sys.exit(f"I don't know anything about type {gtype}") else: for gtype in arguments.type: guess, encoding = guess_type(gtype, not arguments.lenient) if guess: print('type:', guess, 'encoding:', encoding) else: - sys.exit("I don't know anything about type", gtype) + sys.exit(f"I don't know anything about type {gtype}") if __name__ == '__main__': From 3ade3a603264888137d77f7d80aee20973b073e7 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 20:17:09 +0300 Subject: [PATCH 17/56] Use an extension unknown to macOS --- Lib/test/test_mimetypes.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index f844cad75b2191..ac0e5aa8661ba2 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -324,19 +324,15 @@ def test_guess_extension(self): self.assertEqual(err, '') def test_guess_type(self): - retcode, out, err = self.mimetypes_cmd('-l', 'foo.pic') + retcode, out, err = self.mimetypes_cmd('-l', 'foo.xul') self.assertEqual(retcode, 0) - self.assertIn(out, [ - # Returned from the defaults when mime.types is missing - 'type: image/pict encoding: None', - # May be returned when mime.types is present - 'type: image/x-pict encoding: None' - ]) + self.assertEqual(out, 'type: image/text encoding: None') self.assertEqual(err, '') - retcode, out, err = self.mimetypes_cmd('foo.pic') + # Previously, there was .pic format that macOS knew as strict + retcode, out, err = self.mimetypes_cmd('foo.xul') self.assertEqual(retcode, 1) - self.assertEqual(out, "I don't know anything about type foo.pic") + self.assertEqual(out, "I don't know anything about type foo.xul") self.assertEqual(err, '') if __name__ == "__main__": From 895ac27d127ed8236914f17bc62f5c7f6c301174 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 20:18:41 +0300 Subject: [PATCH 18/56] Fix an incorrect image/text to text/xul --- Lib/test/test_mimetypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index ac0e5aa8661ba2..7b84667854fb97 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -326,7 +326,7 @@ def test_guess_extension(self): def test_guess_type(self): retcode, out, err = self.mimetypes_cmd('-l', 'foo.xul') self.assertEqual(retcode, 0) - self.assertEqual(out, 'type: image/text encoding: None') + self.assertEqual(out, 'type: text/xul encoding: None') self.assertEqual(err, '') # Previously, there was .pic format that macOS knew as strict From 4476b300b813aae0efbd07d41a3b9b6435feef7f Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 20:43:15 +0300 Subject: [PATCH 19/56] Fix stdout/stderr mistesting --- Lib/test/test_mimetypes.py | 8 ++++---- .../Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 7b84667854fb97..3b3d3bc29da5ef 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -315,8 +315,8 @@ def test_guess_extension(self): retcode, out, err = self.mimetypes_cmd('-e', 'image/jpg') self.assertEqual(retcode, 1) - self.assertEqual(out, "I don't know anything about type image/jpg") - self.assertEqual(err, '') + self.assertEqual(out, '') + self.assertEqual(err, "I don't know anything about type image/jpg") retcode, out, err = self.mimetypes_cmd('-e', 'image/jpeg') self.assertEqual(retcode, 0) @@ -332,8 +332,8 @@ def test_guess_type(self): # Previously, there was .pic format that macOS knew as strict retcode, out, err = self.mimetypes_cmd('foo.xul') self.assertEqual(retcode, 1) - self.assertEqual(out, "I don't know anything about type foo.xul") - self.assertEqual(err, '') + self.assertEqual(out, '') + self.assertEqual(err, "I don't know anything about type foo.xul") if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst index 055336abe9627e..ed8dd2769275bb 100644 --- a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst +++ b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst @@ -1,2 +1,3 @@ Command-line :mod:`mimetypes` started to return 1 instead of 0 for abruptions and 2 instead of 1 for incorrect command line parameters. +Also, errors are printed into stderr instead of stdout. From 96e127b63d906ff128540d0d1c8390f6077dde58 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 21:01:14 +0300 Subject: [PATCH 20/56] macOS, maybe Midi is what you don't override? --- Lib/test/test_mimetypes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 3b3d3bc29da5ef..53365ec54d0cc9 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -324,16 +324,16 @@ def test_guess_extension(self): self.assertEqual(err, '') def test_guess_type(self): - retcode, out, err = self.mimetypes_cmd('-l', 'foo.xul') + retcode, out, err = self.mimetypes_cmd('-l', 'foo.mid') self.assertEqual(retcode, 0) - self.assertEqual(out, 'type: text/xul encoding: None') + self.assertEqual(out, 'type: audio/midi encoding: None') self.assertEqual(err, '') # Previously, there was .pic format that macOS knew as strict - retcode, out, err = self.mimetypes_cmd('foo.xul') + retcode, out, err = self.mimetypes_cmd('foo.mid') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, "I don't know anything about type foo.xul") + self.assertEqual(err, "I don't know anything about type foo.mid") if __name__ == "__main__": unittest.main() From 63b762e437e2a8858f7eb0cc660e87b532cb1482 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 21:17:48 +0300 Subject: [PATCH 21/56] One more attempt to fix macOS-specific tests --- Lib/test/test_mimetypes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 53365ec54d0cc9..eaa0cdf045fffb 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -324,16 +324,16 @@ def test_guess_extension(self): self.assertEqual(err, '') def test_guess_type(self): - retcode, out, err = self.mimetypes_cmd('-l', 'foo.mid') + retcode, out, err = self.mimetypes_cmd('-l', 'foo.midi') self.assertEqual(retcode, 0) self.assertEqual(out, 'type: audio/midi encoding: None') self.assertEqual(err, '') # Previously, there was .pic format that macOS knew as strict - retcode, out, err = self.mimetypes_cmd('foo.mid') + retcode, out, err = self.mimetypes_cmd('foo.midi') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, "I don't know anything about type foo.mid") + self.assertEqual(err, "I don't know anything about type foo.midi") if __name__ == "__main__": unittest.main() From 543d0037214d279d41db795e0fff161f8beafc39 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 21:19:58 +0300 Subject: [PATCH 22/56] Maybe pict? --- Lib/test/test_mimetypes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index eaa0cdf045fffb..42ea20f5cd0387 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -324,16 +324,16 @@ def test_guess_extension(self): self.assertEqual(err, '') def test_guess_type(self): - retcode, out, err = self.mimetypes_cmd('-l', 'foo.midi') + retcode, out, err = self.mimetypes_cmd('-l', 'foo.pict') self.assertEqual(retcode, 0) - self.assertEqual(out, 'type: audio/midi encoding: None') + self.assertEqual(out, 'type: image/pict encoding: None') self.assertEqual(err, '') # Previously, there was .pic format that macOS knew as strict - retcode, out, err = self.mimetypes_cmd('foo.midi') + retcode, out, err = self.mimetypes_cmd('foo.pict') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, "I don't know anything about type foo.midi") + self.assertEqual(err, "I don't know anything about type foo.pict") if __name__ == "__main__": unittest.main() From 55c6165bce72a0476c9dfb77ec92d857643ca3a5 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 22:08:29 +0300 Subject: [PATCH 23/56] Skip the strict case where mime.types is used --- Lib/test/test_mimetypes.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 42ea20f5cd0387..27d4bc8750af57 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -324,16 +324,20 @@ def test_guess_extension(self): self.assertEqual(err, '') def test_guess_type(self): - retcode, out, err = self.mimetypes_cmd('-l', 'foo.pict') + retcode, out, err = self.mimetypes_cmd('-l', 'foo.pic') self.assertEqual(retcode, 0) self.assertEqual(out, 'type: image/pict encoding: None') self.assertEqual(err, '') - # Previously, there was .pic format that macOS knew as strict - retcode, out, err = self.mimetypes_cmd('foo.pict') + @unittest.skipIf( + sys.platform == "macos", + "mime.types knows the whole common_types so they are marked as strict" + ) + 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, "I don't know anything about type foo.pict") + self.assertEqual(err, "I don't know anything about type foo.pic") if __name__ == "__main__": unittest.main() From 54f9889081e5b9252a8adb17079ebedd450658a5 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 22:32:24 +0300 Subject: [PATCH 24/56] Temporarily disable all test but the broken one --- .github/workflows/build.yml | 271 ------------------------------------ Lib/test/test_mimetypes.py | 4 +- Tools/scripts/run_tests.py | 2 +- 3 files changed, 3 insertions(+), 274 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d800442ad07e36..e643e679687494 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,132 +26,10 @@ permissions: contents: read jobs: - check_source: - name: 'Check for source changes' - runs-on: ubuntu-latest - outputs: - run_tests: ${{ steps.check.outputs.run_tests }} - run_ssl_tests: ${{ steps.check.outputs.run_ssl_tests }} - steps: - - uses: actions/checkout@v3 - - name: Check for source changes - id: check - run: | - if [ -z "$GITHUB_BASE_REF" ]; then - echo '::set-output name=run_tests::true' - echo '::set-output name=run_ssl_tests::true' - else - git fetch origin $GITHUB_BASE_REF --depth=1 - # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more - # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots), - # but it requires to download more commits (this job uses - # "git fetch --depth=1"). - # - # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git - # 2.26, but Git 2.28 is stricter and fails with "no merge base". - # - # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on - # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF - # into the PR branch anyway. - # - # https://github.com/python/core-workflow/issues/373 - git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo '::set-output name=run_tests::true' || true - git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE '(ssl|hashlib|hmac|^.github)' && echo '::set-output name=run_ssl_tests::true' || true - fi - - check_generated_files: - name: 'Check if generated files are up to date' - runs-on: ubuntu-latest - needs: check_source - if: needs.check_source.outputs.run_tests == 'true' - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 - - name: Install Dependencies - run: sudo ./.github/workflows/posix-deps-apt.sh - - name: Add ccache to PATH - run: echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV - - name: Configure ccache action - uses: hendrikmuhs/ccache-action@v1 - - name: Check Autoconf version 2.69 and aclocal 1.16.3 - run: | - grep "Generated by GNU Autoconf 2.69" configure - grep "aclocal 1.16.3" aclocal.m4 - grep -q "runstatedir" configure - grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4 - - name: Configure CPython - run: | - # Build Python with the libpython dynamic library - ./configure --with-pydebug --enable-shared - - name: Regenerate autoconf files with container image - run: make regen-configure - - name: Build CPython - run: | - # Deepfreeze will usually cause global objects to be added or removed, - # so we run it before regen-global-objects gets rum (in regen-all). - make regen-deepfreeze - make -j4 regen-all - make regen-stdlib-module-names - - name: Check for changes - run: | - git add -u - changes=$(git status --porcelain) - # Check for changes in regenerated files - if test -n "$changes"; then - echo "Generated files not up to date." - echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)" - echo "configure files must be regenerated with a specific version of autoconf." - echo "$changes" - echo "" - git diff --staged || true - exit 1 - fi - - name: Check exported libpython symbols - run: make smelly - - name: Check limited ABI symbols - run: make check-limited-abi - - build_win32: - name: 'Windows (x86)' - runs-on: windows-latest - needs: check_source - if: needs.check_source.outputs.run_tests == 'true' - env: - IncludeUwp: 'true' - steps: - - uses: actions/checkout@v3 - - name: Build CPython - run: .\PCbuild\build.bat -e -d -p Win32 - timeout-minutes: 30 - - name: Display build info - run: .\python.bat -m test.pythoninfo - - name: Tests - run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 - - build_win_amd64: - name: 'Windows (x64)' - runs-on: windows-latest - needs: check_source - if: needs.check_source.outputs.run_tests == 'true' - env: - IncludeUwp: 'true' - steps: - - uses: actions/checkout@v3 - - name: Register MSVC problem matcher - run: echo "::add-matcher::.github/problem-matchers/msvc.json" - - name: Build CPython - run: .\PCbuild\build.bat -e -d -p x64 - timeout-minutes: 30 - - name: Display build info - run: .\python.bat -m test.pythoninfo - - name: Tests - run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 - build_macos: name: 'macOS' runs-on: macos-latest needs: check_source - if: needs.check_source.outputs.run_tests == 'true' env: PYTHONSTRICTEXTENSIONBUILD: 1 steps: @@ -168,152 +46,3 @@ jobs: run: make pythoninfo - name: Tests run: make buildbottest TESTOPTS="-j4 -uall,-cpu" - - build_ubuntu: - name: 'Ubuntu' - runs-on: ubuntu-20.04 - needs: check_source - if: needs.check_source.outputs.run_tests == 'true' - env: - OPENSSL_VER: 1.1.1n - PYTHONSTRICTEXTENSIONBUILD: 1 - steps: - - uses: actions/checkout@v3 - - name: Register gcc problem matcher - run: echo "::add-matcher::.github/problem-matchers/gcc.json" - - name: Install Dependencies - run: sudo ./.github/workflows/posix-deps-apt.sh - - name: Configure OpenSSL env vars - run: | - echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV - echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV - - name: 'Restore OpenSSL build' - id: cache-openssl - uses: actions/cache@v3 - with: - path: ./multissl/openssl/${{ env.OPENSSL_VER }} - key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} - - name: Install OpenSSL - if: steps.cache-openssl.outputs.cache-hit != 'true' - run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux - - name: Add ccache to PATH - run: | - echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV - - name: Configure ccache action - uses: hendrikmuhs/ccache-action@v1 - - name: Setup directory envs for out-of-tree builds - run: | - echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV - echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV - - name: Create directories for read-only out-of-tree builds - run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR - - name: Bind mount sources read-only - run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR - - name: Configure CPython out-of-tree - working-directory: ${{ env.CPYTHON_BUILDDIR }} - run: ../cpython-ro-srcdir/configure --with-pydebug --with-openssl=$OPENSSL_DIR - - name: Build CPython out-of-tree - working-directory: ${{ env.CPYTHON_BUILDDIR }} - run: make -j4 - - name: Display build info - working-directory: ${{ env.CPYTHON_BUILDDIR }} - run: make pythoninfo - - name: Remount sources writable for tests - # some tests write to srcdir, lack of pyc files slows down testing - run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw - - name: Tests - working-directory: ${{ env.CPYTHON_BUILDDIR }} - run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" - - build_ubuntu_ssltests: - name: 'Ubuntu SSL tests with OpenSSL' - runs-on: ubuntu-20.04 - needs: check_source - if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_ssl_tests == 'true' - strategy: - fail-fast: false - matrix: - openssl_ver: [1.1.1n, 3.0.2] - env: - OPENSSL_VER: ${{ matrix.openssl_ver }} - MULTISSL_DIR: ${{ github.workspace }}/multissl - OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }} - LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib - steps: - - uses: actions/checkout@v3 - - name: Register gcc problem matcher - run: echo "::add-matcher::.github/problem-matchers/gcc.json" - - name: Install Dependencies - run: sudo ./.github/workflows/posix-deps-apt.sh - - name: Configure OpenSSL env vars - run: | - echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV - echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV - - name: 'Restore OpenSSL build' - id: cache-openssl - uses: actions/cache@v3 - with: - path: ./multissl/openssl/${{ env.OPENSSL_VER }} - key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} - - name: Install OpenSSL - if: steps.cache-openssl.outputs.cache-hit != 'true' - run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux - - name: Add ccache to PATH - run: | - echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV - - name: Configure ccache action - uses: hendrikmuhs/ccache-action@v1 - - name: Configure CPython - run: ./configure --with-pydebug --with-openssl=$OPENSSL_DIR - - name: Build CPython - run: make -j4 - - name: Display build info - run: make pythoninfo - - name: SSL tests - run: ./python Lib/test/ssltests.py - - - build_asan: - name: 'Address sanitizer' - runs-on: ubuntu-20.04 - needs: check_source - if: needs.check_source.outputs.run_tests == 'true' - env: - OPENSSL_VER: 1.1.1n - PYTHONSTRICTEXTENSIONBUILD: 1 - ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0 - steps: - - uses: actions/checkout@v3 - - name: Register gcc problem matcher - run: echo "::add-matcher::.github/problem-matchers/gcc.json" - - name: Install Dependencies - run: sudo ./.github/workflows/posix-deps-apt.sh - - name: Configure OpenSSL env vars - run: | - echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV - echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV - - name: 'Restore OpenSSL build' - id: cache-openssl - uses: actions/cache@v3 - with: - path: ./multissl/openssl/${{ env.OPENSSL_VER }} - key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} - - name: Install OpenSSL - if: steps.cache-openssl.outputs.cache-hit != 'true' - run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux - - name: Add ccache to PATH - run: | - echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV - - name: Configure ccache action - uses: hendrikmuhs/ccache-action@v1 - - name: Configure CPython - run: ./configure --with-address-sanitizer --without-pymalloc - - name: Build CPython - run: make -j4 - - name: Display build info - run: make pythoninfo - - name: Tests - run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 27d4bc8750af57..d71005f8ff8809 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -330,8 +330,8 @@ def test_guess_type(self): self.assertEqual(err, '') @unittest.skipIf( - sys.platform == "macos", - "mime.types knows the whole common_types so they are marked as strict" + sys.platform == 'darwin', + 'mime.types knows the whole common_types so they are marked as strict' ) def test_guess_type_conflicting_with_mimetypes(self): retcode, out, err = self.mimetypes_cmd('foo.pic') diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py index 48feb3f778ee8d..4cc1ab8baff917 100644 --- a/Tools/scripts/run_tests.py +++ b/Tools/scripts/run_tests.py @@ -33,7 +33,7 @@ def main(regrtest_args): args.extend(['-m', 'test', # Run the test suite '-r', # Randomize test order - '-w', # Re-run failed tests in verbose mode + 'test_mimetypes' ]) if sys.platform == 'win32': args.append('-n') # Silence alerts under Windows From be068976489b0aeb786299ba82273ab5c5cf490e Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 22:38:19 +0300 Subject: [PATCH 25/56] Temporarily remove doc building too --- .github/workflows/build.yml | 1 - .github/workflows/doc.yml | 59 ------------------------------------- 2 files changed, 60 deletions(-) delete mode 100644 .github/workflows/doc.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e643e679687494..fcd35107f005c4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,7 +29,6 @@ jobs: build_macos: name: 'macOS' runs-on: macos-latest - needs: check_source env: PYTHONSTRICTEXTENSIONBUILD: 1 steps: diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml deleted file mode 100644 index 9cd251648cdeaf..00000000000000 --- a/.github/workflows/doc.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Docs - -on: - workflow_dispatch: - #push: - # branches: - # - 'main' - # - '3.11' - # - '3.10' - # - '3.9' - # - '3.8' - # - '3.7' - # paths: - # - 'Doc/**' - pull_request: - branches: - - 'main' - - '3.11' - - '3.10' - - '3.9' - - '3.8' - - '3.7' - paths: - - 'Doc/**' - - 'Misc/**' - -permissions: - contents: read - -jobs: - build_doc: - name: 'Docs' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Register Sphinx problem matcher - run: echo "::add-matcher::.github/problem-matchers/sphinx.json" - - name: 'Install Dependencies' - run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install wamerican - - name: 'Configure CPython' - run: ./configure --with-pydebug - - name: 'Build CPython' - run: make -j4 - - name: 'Install build dependencies' - run: make -C Doc/ PYTHON=../python venv - # Run "check doctest html" as 3 steps to get a more readable output - # in the web UI - - name: 'Check documentation' - run: make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going" check - # Use "xvfb-run" since some doctest tests open GUI windows - - name: 'Run documentation doctest' - run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going" doctest - - name: 'Build HTML documentation' - run: make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going" html - - name: 'Upload' - uses: actions/upload-artifact@v3 - with: - name: doc-html - path: Doc/build/html From 6af766869ce03af17f1484a7b727f9e8f2f17a10 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 22:57:55 +0300 Subject: [PATCH 26/56] temporary: Add printing of a platform name --- Lib/test/test_mimetypes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index d71005f8ff8809..be8eeeb17a9243 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -328,6 +328,7 @@ def test_guess_type(self): self.assertEqual(retcode, 0) self.assertEqual(out, 'type: image/pict encoding: None') self.assertEqual(err, '') + print(f'====================================================================={sys.platform}') @unittest.skipIf( sys.platform == 'darwin', From 037b68e70272310e7f47981db8f34b857ca105ae Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 23:13:49 +0300 Subject: [PATCH 27/56] temporary: Another attempt --- Lib/test/test_mimetypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index be8eeeb17a9243..b92c0f8b6343ca 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -324,11 +324,11 @@ def test_guess_extension(self): self.assertEqual(err, '') def test_guess_type(self): + print(f'====================================================================={sys.platform}') retcode, out, err = self.mimetypes_cmd('-l', 'foo.pic') self.assertEqual(retcode, 0) self.assertEqual(out, 'type: image/pict encoding: None') self.assertEqual(err, '') - print(f'====================================================================={sys.platform}') @unittest.skipIf( sys.platform == 'darwin', From de4f377b609208f573a01cf099c952c12d5928ca Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 23:22:24 +0300 Subject: [PATCH 28/56] Return to MIDI --- Lib/test/test_mimetypes.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index b92c0f8b6343ca..ff4bdbf7f1de1a 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -324,10 +324,9 @@ def test_guess_extension(self): self.assertEqual(err, '') def test_guess_type(self): - print(f'====================================================================={sys.platform}') - retcode, out, err = self.mimetypes_cmd('-l', 'foo.pic') + retcode, out, err = self.mimetypes_cmd('-l', 'foo.mid') self.assertEqual(retcode, 0) - self.assertEqual(out, 'type: image/pict encoding: None') + self.assertEqual(out, 'type: audio/midi encoding: None') self.assertEqual(err, '') @unittest.skipIf( @@ -335,10 +334,10 @@ def test_guess_type(self): 'mime.types knows the whole common_types so they are marked as strict' ) def test_guess_type_conflicting_with_mimetypes(self): - retcode, out, err = self.mimetypes_cmd('foo.pic') + retcode, out, err = self.mimetypes_cmd('foo.mid') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, "I don't know anything about type foo.pic") + self.assertEqual(err, "I don't know anything about type foo.mid") if __name__ == "__main__": unittest.main() From a8e77189051d76cc3e955a7a559b9cb3640c04f2 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sat, 28 May 2022 23:31:19 +0300 Subject: [PATCH 29/56] Restore build scripts --- .github/workflows/build.yml | 272 ++++++++++++++++++++++++++++++++++++ .github/workflows/doc.yml | 59 ++++++++ Tools/scripts/run_tests.py | 2 +- 3 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/doc.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fcd35107f005c4..d800442ad07e36 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,9 +26,132 @@ permissions: contents: read jobs: + check_source: + name: 'Check for source changes' + runs-on: ubuntu-latest + outputs: + run_tests: ${{ steps.check.outputs.run_tests }} + run_ssl_tests: ${{ steps.check.outputs.run_ssl_tests }} + steps: + - uses: actions/checkout@v3 + - name: Check for source changes + id: check + run: | + if [ -z "$GITHUB_BASE_REF" ]; then + echo '::set-output name=run_tests::true' + echo '::set-output name=run_ssl_tests::true' + else + git fetch origin $GITHUB_BASE_REF --depth=1 + # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more + # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots), + # but it requires to download more commits (this job uses + # "git fetch --depth=1"). + # + # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git + # 2.26, but Git 2.28 is stricter and fails with "no merge base". + # + # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on + # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF + # into the PR branch anyway. + # + # https://github.com/python/core-workflow/issues/373 + git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo '::set-output name=run_tests::true' || true + git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE '(ssl|hashlib|hmac|^.github)' && echo '::set-output name=run_ssl_tests::true' || true + fi + + check_generated_files: + name: 'Check if generated files are up to date' + runs-on: ubuntu-latest + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - name: Install Dependencies + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Add ccache to PATH + run: echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Configure ccache action + uses: hendrikmuhs/ccache-action@v1 + - name: Check Autoconf version 2.69 and aclocal 1.16.3 + run: | + grep "Generated by GNU Autoconf 2.69" configure + grep "aclocal 1.16.3" aclocal.m4 + grep -q "runstatedir" configure + grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4 + - name: Configure CPython + run: | + # Build Python with the libpython dynamic library + ./configure --with-pydebug --enable-shared + - name: Regenerate autoconf files with container image + run: make regen-configure + - name: Build CPython + run: | + # Deepfreeze will usually cause global objects to be added or removed, + # so we run it before regen-global-objects gets rum (in regen-all). + make regen-deepfreeze + make -j4 regen-all + make regen-stdlib-module-names + - name: Check for changes + run: | + git add -u + changes=$(git status --porcelain) + # Check for changes in regenerated files + if test -n "$changes"; then + echo "Generated files not up to date." + echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)" + echo "configure files must be regenerated with a specific version of autoconf." + echo "$changes" + echo "" + git diff --staged || true + exit 1 + fi + - name: Check exported libpython symbols + run: make smelly + - name: Check limited ABI symbols + run: make check-limited-abi + + build_win32: + name: 'Windows (x86)' + runs-on: windows-latest + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + IncludeUwp: 'true' + steps: + - uses: actions/checkout@v3 + - name: Build CPython + run: .\PCbuild\build.bat -e -d -p Win32 + timeout-minutes: 30 + - name: Display build info + run: .\python.bat -m test.pythoninfo + - name: Tests + run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 + + build_win_amd64: + name: 'Windows (x64)' + runs-on: windows-latest + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + IncludeUwp: 'true' + steps: + - uses: actions/checkout@v3 + - name: Register MSVC problem matcher + run: echo "::add-matcher::.github/problem-matchers/msvc.json" + - name: Build CPython + run: .\PCbuild\build.bat -e -d -p x64 + timeout-minutes: 30 + - name: Display build info + run: .\python.bat -m test.pythoninfo + - name: Tests + run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 + build_macos: name: 'macOS' runs-on: macos-latest + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' env: PYTHONSTRICTEXTENSIONBUILD: 1 steps: @@ -45,3 +168,152 @@ jobs: run: make pythoninfo - name: Tests run: make buildbottest TESTOPTS="-j4 -uall,-cpu" + + build_ubuntu: + name: 'Ubuntu' + runs-on: ubuntu-20.04 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + OPENSSL_VER: 1.1.1n + PYTHONSTRICTEXTENSIONBUILD: 1 + steps: + - uses: actions/checkout@v3 + - name: Register gcc problem matcher + run: echo "::add-matcher::.github/problem-matchers/gcc.json" + - name: Install Dependencies + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Configure OpenSSL env vars + run: | + echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV + echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV + - name: 'Restore OpenSSL build' + id: cache-openssl + uses: actions/cache@v3 + with: + path: ./multissl/openssl/${{ env.OPENSSL_VER }} + key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} + - name: Install OpenSSL + if: steps.cache-openssl.outputs.cache-hit != 'true' + run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux + - name: Add ccache to PATH + run: | + echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Configure ccache action + uses: hendrikmuhs/ccache-action@v1 + - name: Setup directory envs for out-of-tree builds + run: | + echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV + echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV + - name: Create directories for read-only out-of-tree builds + run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR + - name: Bind mount sources read-only + run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR + - name: Configure CPython out-of-tree + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: ../cpython-ro-srcdir/configure --with-pydebug --with-openssl=$OPENSSL_DIR + - name: Build CPython out-of-tree + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: make -j4 + - name: Display build info + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: make pythoninfo + - name: Remount sources writable for tests + # some tests write to srcdir, lack of pyc files slows down testing + run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw + - name: Tests + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" + + build_ubuntu_ssltests: + name: 'Ubuntu SSL tests with OpenSSL' + runs-on: ubuntu-20.04 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_ssl_tests == 'true' + strategy: + fail-fast: false + matrix: + openssl_ver: [1.1.1n, 3.0.2] + env: + OPENSSL_VER: ${{ matrix.openssl_ver }} + MULTISSL_DIR: ${{ github.workspace }}/multissl + OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }} + LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib + steps: + - uses: actions/checkout@v3 + - name: Register gcc problem matcher + run: echo "::add-matcher::.github/problem-matchers/gcc.json" + - name: Install Dependencies + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Configure OpenSSL env vars + run: | + echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV + echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV + - name: 'Restore OpenSSL build' + id: cache-openssl + uses: actions/cache@v3 + with: + path: ./multissl/openssl/${{ env.OPENSSL_VER }} + key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} + - name: Install OpenSSL + if: steps.cache-openssl.outputs.cache-hit != 'true' + run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux + - name: Add ccache to PATH + run: | + echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Configure ccache action + uses: hendrikmuhs/ccache-action@v1 + - name: Configure CPython + run: ./configure --with-pydebug --with-openssl=$OPENSSL_DIR + - name: Build CPython + run: make -j4 + - name: Display build info + run: make pythoninfo + - name: SSL tests + run: ./python Lib/test/ssltests.py + + + build_asan: + name: 'Address sanitizer' + runs-on: ubuntu-20.04 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + OPENSSL_VER: 1.1.1n + PYTHONSTRICTEXTENSIONBUILD: 1 + ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0 + steps: + - uses: actions/checkout@v3 + - name: Register gcc problem matcher + run: echo "::add-matcher::.github/problem-matchers/gcc.json" + - name: Install Dependencies + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Configure OpenSSL env vars + run: | + echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV + echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV + - name: 'Restore OpenSSL build' + id: cache-openssl + uses: actions/cache@v3 + with: + path: ./multissl/openssl/${{ env.OPENSSL_VER }} + key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} + - name: Install OpenSSL + if: steps.cache-openssl.outputs.cache-hit != 'true' + run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux + - name: Add ccache to PATH + run: | + echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Configure ccache action + uses: hendrikmuhs/ccache-action@v1 + - name: Configure CPython + run: ./configure --with-address-sanitizer --without-pymalloc + - name: Build CPython + run: make -j4 + - name: Display build info + run: make pythoninfo + - name: Tests + run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml new file mode 100644 index 00000000000000..9cd251648cdeaf --- /dev/null +++ b/.github/workflows/doc.yml @@ -0,0 +1,59 @@ +name: Docs + +on: + workflow_dispatch: + #push: + # branches: + # - 'main' + # - '3.11' + # - '3.10' + # - '3.9' + # - '3.8' + # - '3.7' + # paths: + # - 'Doc/**' + pull_request: + branches: + - 'main' + - '3.11' + - '3.10' + - '3.9' + - '3.8' + - '3.7' + paths: + - 'Doc/**' + - 'Misc/**' + +permissions: + contents: read + +jobs: + build_doc: + name: 'Docs' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Register Sphinx problem matcher + run: echo "::add-matcher::.github/problem-matchers/sphinx.json" + - name: 'Install Dependencies' + run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install wamerican + - name: 'Configure CPython' + run: ./configure --with-pydebug + - name: 'Build CPython' + run: make -j4 + - name: 'Install build dependencies' + run: make -C Doc/ PYTHON=../python venv + # Run "check doctest html" as 3 steps to get a more readable output + # in the web UI + - name: 'Check documentation' + run: make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going" check + # Use "xvfb-run" since some doctest tests open GUI windows + - name: 'Run documentation doctest' + run: xvfb-run make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going" doctest + - name: 'Build HTML documentation' + run: make -C Doc/ PYTHON=../python SPHINXOPTS="-q -W --keep-going" html + - name: 'Upload' + uses: actions/upload-artifact@v3 + with: + name: doc-html + path: Doc/build/html diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py index 4cc1ab8baff917..48feb3f778ee8d 100644 --- a/Tools/scripts/run_tests.py +++ b/Tools/scripts/run_tests.py @@ -33,7 +33,7 @@ def main(regrtest_args): args.extend(['-m', 'test', # Run the test suite '-r', # Randomize test order - 'test_mimetypes' + '-w', # Re-run failed tests in verbose mode ]) if sys.platform == 'win32': args.append('-n') # Silence alerts under Windows From df910bc0ddeca1c6aefb265beabe06fd60267b4e Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sun, 29 May 2022 00:09:12 +0300 Subject: [PATCH 30/56] One more attempt --- Lib/test/test_mimetypes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index ff4bdbf7f1de1a..c68b023bf0b56c 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -324,9 +324,9 @@ def test_guess_extension(self): self.assertEqual(err, '') def test_guess_type(self): - retcode, out, err = self.mimetypes_cmd('-l', 'foo.mid') + retcode, out, err = self.mimetypes_cmd('-l', 'foo.webp') self.assertEqual(retcode, 0) - self.assertEqual(out, 'type: audio/midi encoding: None') + self.assertEqual(out, 'type: image/webp encoding: None') self.assertEqual(err, '') @unittest.skipIf( @@ -334,10 +334,10 @@ def test_guess_type(self): 'mime.types knows the whole common_types so they are marked as strict' ) def test_guess_type_conflicting_with_mimetypes(self): - retcode, out, err = self.mimetypes_cmd('foo.mid') + retcode, out, err = self.mimetypes_cmd('foo.webp') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, "I don't know anything about type foo.mid") + self.assertEqual(err, "I don't know anything about type foo.webp") if __name__ == "__main__": unittest.main() From cf2a7687adfefa8ae8e912ca5986e8cdcf6d0e28 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Sun, 29 May 2022 17:29:23 +0300 Subject: [PATCH 31/56] Fix a typo --- Lib/mimetypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index f5c75f9dae4ada..e641e1c942213c 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -609,7 +609,7 @@ def _main(): parser.add_argument( '-l', '--lenient', action='store_true', - help='additianally search for common but non-standard types' + help='additionally search for common but non-standard types' ) parser.add_argument('type', nargs='+', help='a type to search') arguments = parser.parse_args() From c975d4c0646034138f0f909f471f7235ded97393 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Thu, 2 Jun 2022 09:38:43 +0300 Subject: [PATCH 32/56] Move a documentation-related news entry --- .../2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/{Library => Documentation}/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst (100%) diff --git a/Misc/NEWS.d/next/Library/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst b/Misc/NEWS.d/next/Documentation/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst similarity index 100% rename from Misc/NEWS.d/next/Library/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst rename to Misc/NEWS.d/next/Documentation/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst From bc1c707c4649d058825a7de3f426167726a81669 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Fri, 10 Jun 2022 22:46:43 +0300 Subject: [PATCH 33/56] Apply suggestions from the @AA-Turner's code review Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- Doc/library/mimetypes.rst | 2 +- .../Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 63d29a1d0eac50..a4a94b7c24aa46 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -288,7 +288,7 @@ It is as simple as: The following options are accepted: -.. program:: filecmp +.. program:: mimetypes .. cmdoption:: -h, --help diff --git a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst index ed8dd2769275bb..0fb651d048a9ab 100644 --- a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst +++ b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst @@ -1,3 +1,3 @@ -Command-line :mod:`mimetypes` started to return 1 instead of 0 for -abruptions and 2 instead of 1 for incorrect command line parameters. -Also, errors are printed into stderr instead of stdout. +Command-line :mod:`mimetypes` started to exit with 1 instead of 0 +on failure and 2 instead of 1 for incorrect command line parameters. +Also, errors are printed to stderr instead of stdout. From aeba8202d41534c62cd33379b00b7663476dcd3e Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 25 Oct 2022 09:41:50 +0400 Subject: [PATCH 34/56] Make CLI tests more strict --- Lib/test/test_mimetypes.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index c68b023bf0b56c..765d114c3f8317 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -286,14 +286,10 @@ def test__all__(self): class MimetypesCliTestCase(unittest.TestCase): - @classmethod - def to_string(cls, stream): - return stream.decode('ascii').strip() - @classmethod def mimetypes_cmd(cls, *args, **kwargs): result, _ = run_python_until_end('-m', 'mimetypes', *args) - return result.rc, cls.to_string(result.out), cls.to_string(result.err) + return result.rc, result.out.decode(), result.err.decode() def test_help_option(self): retcode, out, err = self.mimetypes_cmd('-h') From c94593f5c6fc7934477c00b792eb48113279481f Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 25 Oct 2022 20:38:13 +0400 Subject: [PATCH 35/56] Add newlines into assertEqual reference strings --- Lib/test/test_mimetypes.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 765d114c3f8317..01d6932ed71126 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -1,5 +1,6 @@ import io import mimetypes +from os import linesep import pathlib import sys import unittest.mock @@ -306,34 +307,34 @@ 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') + 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, "I don't know anything about type image/jpg") + self.assertEqual(err, f"I don't know anything about type image/jpg{linesep}") retcode, out, err = self.mimetypes_cmd('-e', 'image/jpeg') self.assertEqual(retcode, 0) - self.assertEqual(out, '.jpg') + 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') + self.assertEqual(out, f'type: image/webp encoding: None{linesep}') self.assertEqual(err, '') @unittest.skipIf( sys.platform == 'darwin', - 'mime.types knows the whole common_types so they are marked as strict' + 'macOS lists common_types in mime.types thus making them always known' ) def test_guess_type_conflicting_with_mimetypes(self): retcode, out, err = self.mimetypes_cmd('foo.webp') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, "I don't know anything about type foo.webp") + self.assertEqual(err, f"I don't know anything about type foo.webp{linesep}") if __name__ == "__main__": unittest.main() From 8b20082b3363d737a765ece3d843e055fde8ef5e Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 25 Oct 2022 20:26:39 +0400 Subject: [PATCH 36/56] Clarify the NEWS entries --- .../2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst | 2 +- .../Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS.d/next/Documentation/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst b/Misc/NEWS.d/next/Documentation/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst index 3350e57f70f309..08c37c8a77046b 100644 --- a/Misc/NEWS.d/next/Documentation/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst +++ b/Misc/NEWS.d/next/Documentation/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst @@ -1 +1 @@ -Added *Command-Line Usage* section for :mod:`mimetypes`. +Added *Command-Line Usage* section for :mod:`mimetypes`. Patch by Oleg Iarygin. diff --git a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst index 0fb651d048a9ab..36d1a2cf0291e1 100644 --- a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst +++ b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst @@ -1,3 +1,3 @@ -Command-line :mod:`mimetypes` started to exit with 1 instead of 0 -on failure and 2 instead of 1 for incorrect command line parameters. -Also, errors are printed to stderr instead of stdout. +Command-line :mod:`mimetypes` now exits with ``1`` instead of ``0`` +on failure and ``2`` instead of ``1`` on incorrect command line parameters. +Also, errors are printed to stderr instead of stdout. Patch by Oleg Iarygin. From 407413ddae178cff68e7cae04ed9dde9f6dcf9b8 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 11:23:57 +0400 Subject: [PATCH 37/56] Slightly reword documentation --- Doc/library/mimetypes.rst | 46 ++++++++++++++++++++++++++++++++++----- Lib/mimetypes.py | 1 + 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index a4a94b7c24aa46..5e0e023abd5315 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -280,7 +280,6 @@ Command-Line Usage ------------------ The :mod:`mimetypes` module can be executed as a script from the command line. -It is as simple as: .. code-block:: sh @@ -290,18 +289,55 @@ The following options are accepted: .. program:: mimetypes -.. cmdoption:: -h, --help +.. cmdoption:: -h + --help Show the help message and exit. -.. cmdoption:: -e, --extension +.. cmdoption:: -e + --extension Guess extension instead of type. -.. cmdoption:: -l, --lenient +.. cmdoption:: -l + --lenient - Additionally search of some common, but non-standard types. + Additionally search for some common, but non-standard types.s The script scans the internal database and converts either file extensions to MIME types or vice versa depending on whether ``--extension`` option is specified. + +.. mimetypes-cli-example: + +Command-Line Example +-------------------- + +Here are some examples of typical usage of the :mod:`mimetypes` command +line interface: + +.. code-block:: shell + + # get a MIME type by a file name + $ python -m mimetypes filename.png + type: image/png encoding: None + + # get a MIME type for a rare file format + $ python -m mimetypes filename.pict + I don't know anything about type filename.pict + + # now look in the extended database built into Python + $ python -m mimetypes -l filename.pict + type: image/pict encoding: None + + # get a file extension by a MIME type + $ python -m mimetypes -e text/javascript + .js + + # get a file extension by a rare MIME type + $ python -m mimetypes -e text/xul + I don't know anything about type text/xul + + # now look in the extended database again + $ python -m mimetypes -e -l text/xul + .xul diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 06f4fbb795a807..b6e9543ece48b7 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -596,6 +596,7 @@ def _default_mime_types(): def _main(): + """Run the mimetypes command line interface.""" from argparse import ArgumentParser parser = ArgumentParser(description='map filename extensions to MIME types') parser.add_argument( From d58d5bac211f5825bc1df52e47accd91d01d0563 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 11:27:59 +0400 Subject: [PATCH 38/56] Reword the news entry --- Misc/ACKS | 1 + .../Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS index 74abcebe21ea60..6e964850ff8b4f 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -814,6 +814,7 @@ Oleg Höfling Robert Hölzl Stefan Hölzl Catalin Iacob +Oleg Iarygin Mihai Ibanescu Ali Ikinci Aaron Iles diff --git a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst index 36d1a2cf0291e1..65c03441a59cca 100644 --- a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst +++ b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst @@ -1,3 +1,3 @@ -Command-line :mod:`mimetypes` now exits with ``1`` instead of ``0`` -on failure and ``2`` instead of ``1`` on incorrect command line parameters. +Command-line :mod:`mimetypes` now exits with ``1`` on failure instead of ``0`` +and ``2`` on incorrect command line parameters instead of ``1``. Also, errors are printed to stderr instead of stdout. Patch by Oleg Iarygin. From 0cfe67ef5b634ab1f62052c112763b745e43b30b Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 11:37:55 +0400 Subject: [PATCH 39/56] Add more examples --- Doc/library/mimetypes.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 5e0e023abd5315..4904061d5ce133 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -308,6 +308,7 @@ The script scans the internal database and converts either file extensions to MIME types or vice versa depending on whether ``--extension`` option is specified. + .. mimetypes-cli-example: Command-Line Example @@ -322,6 +323,14 @@ line interface: $ python -m mimetypes filename.png type: image/png encoding: None + # get a MIME type by a URL + python -m mimetypes http://example.com/filename.txt + type: text/plain encoding: None + + # get a complex MIME type + python -m mimetypes filename.tar.gz + type: application/x-tar encoding: gzip + # get a MIME type for a rare file format $ python -m mimetypes filename.pict I don't know anything about type filename.pict From d2797f062a93a36f8644f650eccc172e9a5f0c51 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 11:56:43 +0400 Subject: [PATCH 40/56] Clarify multi-input usage --- Doc/library/mimetypes.rst | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 4904061d5ce133..b95e9b1cf5dda3 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -308,6 +308,11 @@ The script scans the internal database and converts either file extensions to MIME types or vice versa depending on whether ``--extension`` option is specified. +The script processes input types in supplied order. For each input type, it +writes a line into the standard output stream. For an unknown type, it writes +an error message into a standard error stream end exits with return code +``1``. + .. mimetypes-cli-example: @@ -331,7 +336,7 @@ line interface: python -m mimetypes filename.tar.gz type: application/x-tar encoding: gzip - # get a MIME type for a rare file format + # get a MIME type for a rare file extension $ python -m mimetypes filename.pict I don't know anything about type filename.pict @@ -350,3 +355,15 @@ line interface: # now look in the extended database again $ python -m mimetypes -e -l text/xul .xul + + # try to feed an unknown file extension + $ python -m mimetypes filename.sh filename.nc filename.xxx filename.txt + type: application/x-sh encoding: None + type: application/x-netcdf encoding: None + I don't know anything about type filename.xxx + + # try to feed an unknown MIME type + $ python -m mimetypes -e audio/aac audio/opus audio/future audio/x-wav + .aac + .opus + I don't know anything about type audio/future From fd590f548c4d05fd81aefabc6343a4e768a3513e Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 12:02:32 +0400 Subject: [PATCH 41/56] Further rewording of the notes --- Doc/library/mimetypes.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index b95e9b1cf5dda3..a53bf09481566e 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -302,16 +302,14 @@ The following options are accepted: .. cmdoption:: -l --lenient - Additionally search for some common, but non-standard types.s + Additionally search for some common, but non-standard types. -The script scans the internal database and converts either file extensions to -MIME types or vice versa depending on whether ``--extension`` option is -specified. +The script scans the internal database and converts file extensions to +MIME types if ``--extension`` option is specified, or vice versa if not. -The script processes input types in supplied order. For each input type, it -writes a line into the standard output stream. For an unknown type, it writes -an error message into a standard error stream end exits with return code -``1``. +For each ``type`` entry, the script writes a line into the standard output +stream. For an unknown type, it writes an error message into a standard error +stream end exits with the return code ``1``. .. mimetypes-cli-example: From 1ef41ddc480a7380ddb36b389311524ccb8fdb0d Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 12:26:27 +0400 Subject: [PATCH 42/56] Clarify data source --- Doc/library/mimetypes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index a53bf09481566e..3faf248ec3eab3 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -304,8 +304,8 @@ The following options are accepted: Additionally search for some common, but non-standard types. -The script scans the internal database and converts file extensions to -MIME types if ``--extension`` option is specified, or vice versa if not. +The script converts file extensions to MIME types if ``--extension`` option +is specified, or vice versa if not. For each ``type`` entry, the script writes a line into the standard output stream. For an unknown type, it writes an error message into a standard error From 2797fc4ee924452cb990cd6439b1c22ba4a4a3c4 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 12:32:23 +0400 Subject: [PATCH 43/56] Remove formatting-breaking "don't" from error messages --- Doc/library/mimetypes.rst | 8 ++++---- Lib/mimetypes.py | 4 ++-- .../Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 3faf248ec3eab3..02e1afc89c6bfc 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -336,7 +336,7 @@ line interface: # get a MIME type for a rare file extension $ python -m mimetypes filename.pict - I don't know anything about type filename.pict + error: unknown extension filename.pict # now look in the extended database built into Python $ python -m mimetypes -l filename.pict @@ -348,7 +348,7 @@ line interface: # get a file extension by a rare MIME type $ python -m mimetypes -e text/xul - I don't know anything about type text/xul + error: unknown type text/xul # now look in the extended database again $ python -m mimetypes -e -l text/xul @@ -358,10 +358,10 @@ line interface: $ python -m mimetypes filename.sh filename.nc filename.xxx filename.txt type: application/x-sh encoding: None type: application/x-netcdf encoding: None - I don't know anything about type filename.xxx + error: unknown extension filename.xxx # try to feed an unknown MIME type $ python -m mimetypes -e audio/aac audio/opus audio/future audio/x-wav .aac .opus - I don't know anything about type audio/future + error: unknown type audio/future diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index b6e9543ece48b7..a563b18053b4e0 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -618,14 +618,14 @@ def _main(): if guess: print(guess) else: - sys.exit(f"I don't know anything about type {gtype}") + sys.exit(f"error: unknown type {gtype}") else: for gtype in arguments.type: guess, encoding = guess_type(gtype, not arguments.lenient) if guess: print('type:', guess, 'encoding:', encoding) else: - sys.exit(f"I don't know anything about type {gtype}") + sys.exit(f"error: unknown extension {gtype}") if __name__ == '__main__': diff --git a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst index 65c03441a59cca..44797ce6e015b7 100644 --- a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst +++ b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst @@ -1,3 +1,4 @@ Command-line :mod:`mimetypes` now exits with ``1`` on failure instead of ``0`` and ``2`` on incorrect command line parameters instead of ``1``. -Also, errors are printed to stderr instead of stdout. Patch by Oleg Iarygin. +Also, errors are printed to stderr instead of stdout and their text is made +tighter. Patch by Oleg Iarygin. From 78c0c5051c952e7a2e817c8059e4196d53c84f96 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 12:44:17 +0400 Subject: [PATCH 44/56] Fix a grammar mistake --- Doc/library/mimetypes.rst | 4 ++-- Lib/mimetypes.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 02e1afc89c6bfc..a2df23b0de8b72 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -336,7 +336,7 @@ line interface: # get a MIME type for a rare file extension $ python -m mimetypes filename.pict - error: unknown extension filename.pict + error: unknown extension of filename.pict # now look in the extended database built into Python $ python -m mimetypes -l filename.pict @@ -358,7 +358,7 @@ line interface: $ python -m mimetypes filename.sh filename.nc filename.xxx filename.txt type: application/x-sh encoding: None type: application/x-netcdf encoding: None - error: unknown extension filename.xxx + error: unknown extension of filename.xxx # try to feed an unknown MIME type $ python -m mimetypes -e audio/aac audio/opus audio/future audio/x-wav diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index a563b18053b4e0..2bbd0084d1db7b 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -625,7 +625,7 @@ def _main(): if guess: print('type:', guess, 'encoding:', encoding) else: - sys.exit(f"error: unknown extension {gtype}") + sys.exit(f"error: unknown extension of {gtype}") if __name__ == '__main__': From 1afb6d6b63355e57cfcc86c7620b847a637c716b Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 12:57:51 +0400 Subject: [PATCH 45/56] Make wording tighter --- Doc/library/mimetypes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index a2df23b0de8b72..29c5349c99bd7e 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -308,8 +308,8 @@ The script converts file extensions to MIME types if ``--extension`` option is specified, or vice versa if not. For each ``type`` entry, the script writes a line into the standard output -stream. For an unknown type, it writes an error message into a standard error -stream end exits with the return code ``1``. +stream. If an unknown type occurs, it writes an error message into the +standard error stream and aborts with the return code ``1``. .. mimetypes-cli-example: From a22d630bcc59c327c0179c65771097119c871980 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 13:37:01 +0400 Subject: [PATCH 46/56] Fix tests --- Lib/test/test_mimetypes.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 01d6932ed71126..cd28634051bd4f 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -287,7 +287,6 @@ def test__all__(self): class MimetypesCliTestCase(unittest.TestCase): - @classmethod def mimetypes_cmd(cls, *args, **kwargs): result, _ = run_python_until_end('-m', 'mimetypes', *args) return result.rc, result.out.decode(), result.err.decode() @@ -313,7 +312,7 @@ def test_guess_extension(self): retcode, out, err = self.mimetypes_cmd('-e', 'image/jpg') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, f"I don't know anything about type image/jpg{linesep}") + self.assertEqual(err, f'error: unknown type image/jpg{linesep}') retcode, out, err = self.mimetypes_cmd('-e', 'image/jpeg') self.assertEqual(retcode, 0) @@ -334,7 +333,7 @@ def test_guess_type_conflicting_with_mimetypes(self): retcode, out, err = self.mimetypes_cmd('foo.webp') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, f"I don't know anything about type foo.webp{linesep}") + self.assertEqual(err, f'error: unknown extension of foo.webp{linesep}') if __name__ == "__main__": unittest.main() From b9d530948fe0b105d8cec5e701651a9573236fa8 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin <oleg@arhadthedev.net> Date: Tue, 24 Jan 2023 14:13:04 +0400 Subject: [PATCH 47/56] Remove the command line input prefix --- Doc/library/mimetypes.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 29c5349c99bd7e..6f87bbf267ab81 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -323,7 +323,7 @@ line interface: .. code-block:: shell # get a MIME type by a file name - $ python -m mimetypes filename.png + python -m mimetypes filename.png type: image/png encoding: None # get a MIME type by a URL @@ -335,33 +335,33 @@ line interface: type: application/x-tar encoding: gzip # get a MIME type for a rare file extension - $ python -m mimetypes filename.pict + python -m mimetypes filename.pict error: unknown extension of filename.pict # now look in the extended database built into Python - $ python -m mimetypes -l filename.pict + python -m mimetypes -l filename.pict type: image/pict encoding: None # get a file extension by a MIME type - $ python -m mimetypes -e text/javascript + python -m mimetypes -e text/javascript .js # get a file extension by a rare MIME type - $ python -m mimetypes -e text/xul + python -m mimetypes -e text/xul error: unknown type text/xul # now look in the extended database again - $ python -m mimetypes -e -l text/xul + python -m mimetypes -e -l text/xul .xul # try to feed an unknown file extension - $ python -m mimetypes filename.sh filename.nc filename.xxx filename.txt + python -m mimetypes filename.sh filename.nc filename.xxx filename.txt type: application/x-sh encoding: None type: application/x-netcdf encoding: None error: unknown extension of filename.xxx # try to feed an unknown MIME type - $ python -m mimetypes -e audio/aac audio/opus audio/future audio/x-wav + python -m mimetypes -e audio/aac audio/opus audio/future audio/x-wav .aac .opus error: unknown type audio/future From a9a43f70b518decbf86da7602bb5de5108d0da2c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:22:38 +0200 Subject: [PATCH 48/56] Fix tests --- Lib/test/test_mimetypes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 34856688272f65..5facab6fcbefaf 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -399,14 +399,14 @@ def mimetypes_cmd(cls, *args, **kwargs): def test_help_option(self): retcode, out, err = self.mimetypes_cmd('-h') self.assertEqual(retcode, 0) - self.assertIn('usage: mimetypes.py', out) + 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.assertIn('usage: mimetypes.py', err) + self.assertStartsWith(err, 'usage: ') def test_guess_extension(self): retcode, out, err = self.mimetypes_cmd('-l', '-e', 'image/jpg') From 85727bf473865b4a107c96c935aabdcbebe949e2 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 7 Mar 2025 18:25:13 +0200 Subject: [PATCH 49/56] Fix test --- Lib/test/test_mimetypes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 5facab6fcbefaf..3eee13979f28d4 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -435,10 +435,10 @@ def test_guess_type(self): 'macOS lists common_types in mime.types thus making them always known' ) def test_guess_type_conflicting_with_mimetypes(self): - retcode, out, err = self.mimetypes_cmd('foo.webp') + retcode, out, err = self.mimetypes_cmd('foo.pic') self.assertEqual(retcode, 1) self.assertEqual(out, '') - self.assertEqual(err, f'error: unknown extension of foo.webp{linesep}') + self.assertEqual(err, f'error: unknown extension of foo.pic{linesep}') if __name__ == "__main__": unittest.main() From f1535fd18342e26a1be9bb7cfcc358b8b1507a43 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:09:55 +0200 Subject: [PATCH 50/56] Use console formatting for commands with output --- Doc/library/mimetypes.rst | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 248bdcd3fc44fb..f20183f6ecbfcd 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -355,48 +355,48 @@ Command-Line Example Here are some examples of typical usage of the :mod:`mimetypes` command line interface: -.. code-block:: shell +.. code-block:: console - # get a MIME type by a file name - python -m mimetypes filename.png + $ # get a MIME type by a file name + $ python -m mimetypes filename.png type: image/png encoding: None - # get a MIME type by a URL - python -m mimetypes http://example.com/filename.txt + $ # get a MIME type by a URL + $ python -m mimetypes http://example.com/filename.txt type: text/plain encoding: None - # get a complex MIME type - python -m mimetypes filename.tar.gz + $ # get a complex MIME type + $ python -m mimetypes filename.tar.gz type: application/x-tar encoding: gzip - # get a MIME type for a rare file extension - python -m mimetypes filename.pict + $ # get a MIME type for a rare file extension + $ python -m mimetypes filename.pict error: unknown extension of filename.pict - # now look in the extended database built into Python - python -m mimetypes -l filename.pict + $ # now look in the extended database built into Python + $ python -m mimetypes -l filename.pict type: image/pict encoding: None - # get a file extension by a MIME type - python -m mimetypes -e text/javascript + $ # get a file extension by a MIME type + $ python -m mimetypes -e text/javascript .js - # get a file extension by a rare MIME type - python -m mimetypes -e text/xul + $ # get a file extension by a rare MIME type + $ python -m mimetypes -e text/xul error: unknown type text/xul - # now look in the extended database again - python -m mimetypes -e -l text/xul + $ # now look in the extended database again + $ python -m mimetypes -e -l text/xul .xul - # try to feed an unknown file extension - python -m mimetypes filename.sh filename.nc filename.xxx filename.txt + $ # try to feed an unknown file extension + $ python -m mimetypes filename.sh filename.nc filename.xxx filename.txt type: application/x-sh encoding: None type: application/x-netcdf encoding: None error: unknown extension of filename.xxx - # try to feed an unknown MIME type - python -m mimetypes -e audio/aac audio/opus audio/future audio/x-wav + $ # try to feed an unknown MIME type + $ python -m mimetypes -e audio/aac audio/opus audio/future audio/x-wav .aac .opus error: unknown type audio/future From 8509c06cc16f577ca01277d790afb8944994efc0 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 8 Mar 2025 17:05:46 +0200 Subject: [PATCH 51/56] Docs: default case first, put condition first, avoid Latin, adjust wording --- Doc/library/mimetypes.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index f20183f6ecbfcd..467b478e00612e 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -314,11 +314,11 @@ than one MIME-type database; it provides an interface similar to the one of the Command-Line Usage ------------------ -The :mod:`mimetypes` module can be executed as a script from the command line. +The :mod:`!mimetypes` module can be executed as a script from the command line. .. code-block:: sh - python -m mimetypes [-e] [-l] type [type ...] + python -m mimetypes [-h] [-e] [-l] type [type ...] The following options are accepted: @@ -339,12 +339,13 @@ The following options are accepted: Additionally search for some common, but non-standard types. -The script converts file extensions to MIME types if ``--extension`` option -is specified, or vice versa if not. +By default the script converts MIME types to file extensions. +However, if ``--extension`` is specified, +it converts file extensions to MIME types. For each ``type`` entry, the script writes a line into the standard output stream. If an unknown type occurs, it writes an error message into the -standard error stream and aborts with the return code ``1``. +standard error stream and exits with the return code ``1``. .. mimetypes-cli-example: @@ -352,8 +353,8 @@ standard error stream and aborts with the return code ``1``. Command-Line Example -------------------- -Here are some examples of typical usage of the :mod:`mimetypes` command -line interface: +Here are some examples of typical usage of the :mod:`!mimetypes` command-line +interface: .. code-block:: console From 9ad283c62033c84eef564345af44af1d611a0fcf Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 8 Mar 2025 17:19:25 +0200 Subject: [PATCH 52/56] Use long options in examples so no need to refer back to usage --- Doc/library/mimetypes.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 467b478e00612e..2e5eca83f91abe 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -363,7 +363,7 @@ interface: type: image/png encoding: None $ # get a MIME type by a URL - $ python -m mimetypes http://example.com/filename.txt + $ python -m mimetypes https://example.com/filename.txt type: text/plain encoding: None $ # get a complex MIME type @@ -375,19 +375,19 @@ interface: error: unknown extension of filename.pict $ # now look in the extended database built into Python - $ python -m mimetypes -l filename.pict + $ python -m mimetypes --lenient filename.pict type: image/pict encoding: None $ # get a file extension by a MIME type - $ python -m mimetypes -e text/javascript + $ python -m mimetypes --extension text/javascript .js $ # get a file extension by a rare MIME type - $ python -m mimetypes -e text/xul + $ python -m mimetypes --extension text/xul error: unknown type text/xul $ # now look in the extended database again - $ python -m mimetypes -e -l text/xul + $ python -m mimetypes --extension --lenient text/xul .xul $ # try to feed an unknown file extension @@ -397,7 +397,7 @@ interface: error: unknown extension of filename.xxx $ # try to feed an unknown MIME type - $ python -m mimetypes -e audio/aac audio/opus audio/future audio/x-wav + $ python -m mimetypes --extension audio/aac audio/opus audio/future audio/x-wav .aac .opus error: unknown type audio/future From a2c0d53c099b7913c7c25cddbcd6fe572f1090d7 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 8 Mar 2025 17:29:28 +0200 Subject: [PATCH 53/56] Follow argparse docs and use 'args' --- Lib/mimetypes.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 54795ff7ab05ea..e0ec00a57ec5ce 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -686,18 +686,18 @@ def _main(): help='additionally search for common but non-standard types' ) parser.add_argument('type', nargs='+', help='a type to search') - arguments = parser.parse_args() + args = parser.parse_args() - if arguments.extension: - for gtype in arguments.type: - guess = guess_extension(gtype, not arguments.lenient) + if args.extension: + for gtype in args.type: + guess = guess_extension(gtype, not args.lenient) if guess: print(guess) else: sys.exit(f"error: unknown type {gtype}") else: - for gtype in arguments.type: - guess, encoding = guess_type(gtype, not arguments.lenient) + for gtype in args.type: + guess, encoding = guess_type(gtype, not args.lenient) if guess: print('type:', guess, 'encoding:', encoding) else: From 34e05912c2c10c3b7e78ecfa918965158197dcde Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 8 Mar 2025 22:39:14 +0200 Subject: [PATCH 54/56] Add to What's New, combine NEWS files, update reference, use sentence case https://devguide.python.org/documentation/style-guide/\#capitalization --- Doc/library/cmdline.rst | 2 +- Doc/library/mimetypes.rst | 8 ++++---- Doc/whatsnew/3.14.rst | 7 +++++++ .../2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst | 1 - .../Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst | 7 ++++--- 5 files changed, 16 insertions(+), 9 deletions(-) delete mode 100644 Misc/NEWS.d/next/Documentation/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst diff --git a/Doc/library/cmdline.rst b/Doc/library/cmdline.rst index 78fe95a014ff7c..59629b693ba00f 100644 --- a/Doc/library/cmdline.rst +++ b/Doc/library/cmdline.rst @@ -24,7 +24,7 @@ The following modules have a command-line interface. * :mod:`!idlelib` * :ref:`inspect <inspect-module-cli>` * :ref:`json <json-commandline>` -* :mod:`mimetypes` +* :ref:`mimetypes <mimetypes-cli>` * :mod:`pdb` * :mod:`pickle` * :ref:`pickletools <pickletools-cli>` diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 2e5eca83f91abe..5af69455032d71 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -191,7 +191,7 @@ An example usage of the module:: .. _mimetypes-objects: -MimeTypes Objects +MimeTypes objects ----------------- The :class:`MimeTypes` class may be useful for applications which may want more @@ -309,9 +309,9 @@ than one MIME-type database; it provides an interface similar to the one of the official MIME types, otherwise to the non-standard ones. -.. mimetypes-cli: +.. _mimetypes-cli: -Command-Line Usage +Command-line usage ------------------ The :mod:`!mimetypes` module can be executed as a script from the command line. @@ -350,7 +350,7 @@ standard error stream and exits with the return code ``1``. .. mimetypes-cli-example: -Command-Line Example +Command-line example -------------------- Here are some examples of typical usage of the :mod:`!mimetypes` command-line diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 2402fb23c86b85..2129b3cbd4841a 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -641,6 +641,13 @@ json mimetypes --------- +* Document the command-line for :mod:`mimetypes`. + It now exits with ``1`` on failure instead of ``0`` + and ``2`` on incorrect command-line parameters instead of ``1``. + Also, errors are printed to stderr instead of stdout and their text is made + tighter. + (Contributed by Oleg Iarygin and Hugo van Kemenade in :gh:`93096`.) + * Add MS and :rfc:`8081` MIME types for fonts: * Embedded OpenType: ``application/vnd.ms-fontobject`` diff --git a/Misc/NEWS.d/next/Documentation/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst b/Misc/NEWS.d/next/Documentation/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst deleted file mode 100644 index 08c37c8a77046b..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-05-23-11-53-24.gh-issue-93096.TIuIhx.rst +++ /dev/null @@ -1 +0,0 @@ -Added *Command-Line Usage* section for :mod:`mimetypes`. Patch by Oleg Iarygin. diff --git a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst index 44797ce6e015b7..fb9ca441c7e2da 100644 --- a/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst +++ b/Misc/NEWS.d/next/Library/2022-05-28-19-41-02.gh-issue-93096.qjUyRG.rst @@ -1,4 +1,5 @@ -Command-line :mod:`mimetypes` now exits with ``1`` on failure instead of ``0`` -and ``2`` on incorrect command line parameters instead of ``1``. +Document the command-line for :mod:`mimetypes`. +It now exits with ``1`` on failure instead of ``0`` +and ``2`` on incorrect command-line parameters instead of ``1``. Also, errors are printed to stderr instead of stdout and their text is made -tighter. Patch by Oleg Iarygin. +tighter. Patch by Oleg Iarygin and Hugo van Kemenade. From 80e1734a63f6209c004e0938b0c05356d9836add Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 8 Mar 2025 23:05:12 +0200 Subject: [PATCH 55/56] Hyphen --- Lib/mimetypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index e0ec00a57ec5ce..619c46d24de735 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -670,7 +670,7 @@ def _default_mime_types(): def _main(): - """Run the mimetypes command line interface.""" + """Run the mimetypes command-line interface.""" import sys from argparse import ArgumentParser From 7cb62c5159294a44e90b2a27d24abf182ec02493 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 11 Mar 2025 00:31:42 +0200 Subject: [PATCH 56/56] Update error message --- Lib/mimetypes.py | 2 +- Lib/test/test_mimetypes.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 619c46d24de735..6b94fe3c4df756 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -701,7 +701,7 @@ def _main(): if guess: print('type:', guess, 'encoding:', encoding) else: - sys.exit(f"error: unknown extension of {gtype}") + sys.exit(f"error: media type unknown for {gtype}") if __name__ == '__main__': diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 3eee13979f28d4..b5d1f50099e16a 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -438,7 +438,7 @@ 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: unknown extension of foo.pic{linesep}') + self.assertEqual(err, f'error: media type unknown for foo.pic{linesep}') if __name__ == "__main__": unittest.main()