From 494fba8d9a424bdc21b83bdae23dc03cad8f05c9 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 ` * :ref:`json ` -* :mod:`mimetypes` +* :ref:`mimetypes ` * :mod:`pdb` * :mod:`pickle` * :ref:`pickletools ` 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() pFad - Phonifier reborn

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

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


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy