python / cpython

The Python programming language
https://www.python.org
Other
63.62k stars 30.48k forks source link

mimetypes.add_type should complain when you give it an undotted ext #75223

Open e40d1192-a6a4-43aa-b414-855b7d3116ac opened 7 years ago

e40d1192-a6a4-43aa-b414-855b7d3116ac commented 7 years ago
BPO 31040
Nosy @OddBloke, @jimjjewett, @JulienPalard, @rcj4747
PRs
  • python/cpython#2871
  • python/cpython#2895
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields: ```python assignee = None closed_at = None created_at = labels = ['3.7', 'library', 'docs'] title = 'mimetypes.add_type should complain when you give it an undotted ext' updated_at = user = 'https://github.com/OddBloke' ``` bugs.python.org fields: ```python activity = actor = 'mdk' assignee = 'docs@python' closed = False closed_date = None closer = None components = ['Documentation', 'Library (Lib)'] creation = creator = 'odd_bloke' dependencies = [] files = [] hgrepos = [] issue_num = 31040 keywords = [] message_count = 4.0 messages = ['299135', '306501', '352266', '352286'] nosy_count = 5.0 nosy_names = ['odd_bloke', 'docs@python', 'Jim.Jewett', 'mdk', 'rcj'] pr_nums = ['2871', '2895'] priority = 'normal' resolution = None stage = 'commit review' status = 'open' superseder = None type = None url = 'https://bugs.python.org/issue31040' versions = ['Python 3.7'] ```

    e40d1192-a6a4-43aa-b414-855b7d3116ac commented 7 years ago
    import mimetypes
    
    print(mimetypes.guess_type('foo.manifest'))
    mimetypes.add_type('text/plain', 'manifest')
    print(mimetypes.guess_type('foo.manifest'))

    results in:

    ('application/x-ms-manifest', None)
    ('application/x-ms-manifest', None)

    I (mistakenly) expected the latter print to give me "('text/plain', None)". It doesn't because I should have prepended a . to the second add_type argument.

    I think add_type should error out when given an extension without a dot-prefix, because it's extremely unlikely that code that does so is behaving as intended with the current implementation.

    (At the very least, documentation should be updated to make this expectation clearer.)

    74c4563b-ab1c-43d8-9219-30c4eca796bc commented 7 years ago

    Ideally, use .startswith('.') Instead if find, but this is a clear UI fix. First pull request fixes doc, second fixes code. OK to apply both.

    JulienPalard commented 5 years ago

    I think we should deprecate calling add_type with an empty ext, as I don't think it's a feature, more a side effect of the current implementation.

    But as some may use it like a feature, I asked the current PR to emit a warning, to not break the current implementations.

    To be able to simplify in the future, why not deprecating empty ext so we can remove it in a few versions?

    JulienPalard commented 5 years ago

    I just found a case where the empty mime type is actually usefull, it's in Lib/http/server.py:

        extensions_map = mimetypes.types_map.copy()
        extensions_map.update({
            '': 'application/octet-stream', # Default
            '.py': 'text/plain',
            '.c': 'text/plain',
            '.h': 'text/plain',
            })

    It does *not* uses add_type, but demos the fact that the empty type may be usefull from time to time, maybe don't warn and don't deprecate it at all.

    hugovk commented 2 days ago

    Checking the top 8k PyPI projects:

    Details ```python ❯ python3 ~/github/misc/cpython/search_pypi_top.py -q . mimetypes.add_type ./django_pipeline-3.1.0.tar.gz: django_pipeline-3.1.0/pipeline/utils.py: mimetypes.add_type(type, ext) ./dagster-webserver-1.9.0.tar.gz: dagster-webserver-1.9.0/dagster_webserver/webserver.py: mimetypes.add_type("application/javascript", ".js") ./dagster-webserver-1.9.0.tar.gz: dagster-webserver-1.9.0/dagster_webserver/webserver.py: mimetypes.add_type("text/css", ".css") ./dagster-webserver-1.9.0.tar.gz: dagster-webserver-1.9.0/dagster_webserver/webserver.py: mimetypes.add_type("image/svg+xml", ".svg") ./dash-2.18.1.tar.gz: dash-2.18.1/dash/dash.py: mimetypes.add_type("application/json", ".map", True) ./chainlit-1.3.1.tar.gz: chainlit-1.3.1/chainlit/server.py: mimetypes.add_type("application/javascript", ".js") ./chainlit-1.3.1.tar.gz: chainlit-1.3.1/chainlit/server.py: mimetypes.add_type("text/css", ".css") ./ansible-10.5.0.tar.gz: ansible-10.5.0/ansible_collections/azure/azcollection/plugins/modules/azure_rm_storageblob.py: mimetypes.add_type('application/json', '.json') ./ansible-10.5.0.tar.gz: ansible-10.5.0/ansible_collections/azure/azcollection/plugins/modules/azure_rm_storageblob.py: mimetypes.add_type('application/javascript', '.js') ./ansible-10.5.0.tar.gz: ansible-10.5.0/ansible_collections/azure/azcollection/plugins/modules/azure_rm_storageblob.py: mimetypes.add_type('application/wasm', '.wasm') ./django_filer-3.2.3.tar.gz: django_filer-3.2.3/filer/apps.py: mimetypes.add_type("image/heic", ext) ./django_filer-3.2.3.tar.gz: django_filer-3.2.3/filer/apps.py: mimetypes.add_type("image/webp", ".webp") ./EbookLib-0.18.tar.gz: EbookLib-0.18/ebooklib/utils.py: mimetypes.add_type('application/xhtml+xml', '.xhtml') ./fava-1.29.tar.gz: fava-1.29/src/fava/application.py: mimetypes.add_type("text/javascript", ".js") ./ansible-10.5.0.tar.gz: ansible-10.5.0/ansible_collections/community/general/tests/integration/targets/launchd/files/ansible_test_service.py: mimetypes.add_type('application/json', '.json') ./azure_cli-2.65.0.tar.gz: azure_cli-2.65.0/azure/cli/command_modules/storage/util.py: mimetypes.add_type('application/json', '.json') ./azure_cli-2.65.0.tar.gz: azure_cli-2.65.0/azure/cli/command_modules/storage/util.py: mimetypes.add_type('application/javascript', '.js') ./azure_cli-2.65.0.tar.gz: azure_cli-2.65.0/azure/cli/command_modules/storage/util.py: mimetypes.add_type('application/wasm', '.wasm') ./jupyter_server-2.14.2.tar.gz: jupyter_server-2.14.2/jupyter_server/serverapp.py: mimetypes.add_type("text/css", ".css") ./jupyter_server-2.14.2.tar.gz: jupyter_server-2.14.2/jupyter_server/serverapp.py: mimetypes.add_type("application/javascript", ".js") ./jupyter_server-2.14.2.tar.gz: jupyter_server-2.14.2/jupyter_server/serverapp.py: mimetypes.add_type("application/wasm", ".wasm") ./jupyterlab_server-2.27.3.tar.gz: jupyterlab_server-2.27.3/jupyterlab_server/licenses_handler.py: mimetypes.add_type("text/markdown", ".md") ./locust-2.32.1.tar.gz: locust-2.32.1/locust/web.py: mimetypes.add_type("application/javascript", ".js") ./openpyxl-3.1.5.tar.gz: openpyxl-3.1.5/openpyxl/packaging/manifest.py: mimetypes.add_type('application/xml', ".xml") ./openpyxl-3.1.5.tar.gz: openpyxl-3.1.5/openpyxl/packaging/manifest.py: mimetypes.add_type('application/vnd.openxmlformats-package.relationships+xml', ".rels") ./openpyxl-3.1.5.tar.gz: openpyxl-3.1.5/openpyxl/packaging/manifest.py: mimetypes.add_type("application/vnd.ms-office.vbaProject", ".bin") ./openpyxl-3.1.5.tar.gz: openpyxl-3.1.5/openpyxl/packaging/manifest.py: mimetypes.add_type("application/vnd.openxmlformats-officedocument.vmlDrawing", ".vml") ./openpyxl-3.1.5.tar.gz: openpyxl-3.1.5/openpyxl/packaging/manifest.py: mimetypes.add_type("image/x-emf", ".emf") ./panel-1.5.3.tar.gz: panel-1.5.3/panel/io/resources.py: mimetypes.add_type("application/javascript", ".js") ./platformio-6.1.16.tar.gz: platformio-6.1.16/platformio/home/cli.py: mimetypes.add_type("text/html", ".html") ./platformio-6.1.16.tar.gz: platformio-6.1.16/platformio/home/cli.py: mimetypes.add_type("text/css", ".css") ./platformio-6.1.16.tar.gz: platformio-6.1.16/platformio/home/cli.py: mimetypes.add_type("application/javascript", ".js") ./nicegui-2.5.0.tar.gz: nicegui-2.5.0/nicegui/nicegui.py: mimetypes.add_type('text/javascript', '.js') ./nicegui-2.5.0.tar.gz: nicegui-2.5.0/nicegui/nicegui.py: mimetypes.add_type('text/css', '.css') ./robocorp_storage-1.0.5.tar.gz: robocorp_storage-1.0.5/src/robocorp/storage/__init__.py: mimetypes.add_type(type_, ext) ./prefect-3.1.0.tar.gz: prefect-3.1.0/src/prefect/server/api/server.py: mimetypes.add_type("application/javascript", ".js") ./streamlit-1.39.0.tar.gz: streamlit-1.39.0/streamlit/web/server/app_static_file_handler.py: mimetypes.add_type("image/webp", ".webp") ./streamlit-1.39.0.tar.gz: streamlit-1.39.0/streamlit/web/server/component_request_handler.py: mimetypes.add_type("text/html", ".html") ./streamlit-1.39.0.tar.gz: streamlit-1.39.0/streamlit/web/server/component_request_handler.py: mimetypes.add_type("application/javascript", ".js") ./streamlit-1.39.0.tar.gz: streamlit-1.39.0/streamlit/web/server/component_request_handler.py: mimetypes.add_type("text/css", ".css") ./supervisely-6.73.221.tar.gz: supervisely-6.73.221/supervisely/convert/image/image_converter.py: mimetypes.add_type("image/heic", ".heic") # to extend types_map ./supervisely-6.73.221.tar.gz: supervisely-6.73.221/supervisely/convert/image/image_converter.py: mimetypes.add_type("image/heif", ".heif") # to extend types_map ./supervisely-6.73.221.tar.gz: supervisely-6.73.221/supervisely/convert/image/image_converter.py: mimetypes.add_type("image/jpeg", ".jfif") # to extend types_map ./supervisely-6.73.221.tar.gz: supervisely-6.73.221/supervisely/convert/image/image_converter.py: mimetypes.add_type("image/avif", ".avif") # to extend types_map ./supervisely-6.73.221.tar.gz: supervisely-6.73.221/supervisely/convert/image/image_converter.py: mimetypes.add_type("image/bmp", ".bmp") # to extend types_map ./supervisely-6.73.221.tar.gz: supervisely-6.73.221/supervisely/convert/image/image_helper.py: mimetypes.add_type("image/webp", ".webp") # to extend types_map ./supervisely-6.73.221.tar.gz: supervisely-6.73.221/supervisely/convert/image/image_helper.py: mimetypes.add_type("image/jpeg", ".jfif") # to extend types_map ./python_semantic_release-9.12.0.tar.gz: python_semantic_release-9.12.0/semantic_release/hvcs/github.py: mimetypes.add_type("application/octet-stream", ".whl") ./python_semantic_release-9.12.0.tar.gz: python_semantic_release-9.12.0/semantic_release/hvcs/github.py: mimetypes.add_type("text/markdown", ".md") ./sqlmesh-0.130.1.tar.gz: sqlmesh-0.130.1/web/server/main.py: mimetypes.add_type("application/javascript", ".js") ./sqlmesh-0.130.1.tar.gz: sqlmesh-0.130.1/web/server/main.py: mimetypes.add_type("text/css", ".css") ./trame-3.7.0.tar.gz: trame-3.7.0/trame/app/mimetypes.py: mimetypes.add_type(key, value) ./trame-3.7.0.tar.gz: trame-3.7.0/trame/app/mimetypes.py: mimetypes.add_type(type, ext) ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('image/png', '.png') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('image/jpeg', '.jpeg') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('image/webp', '.webp') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('image/gif', '.gif') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('image/bmp', '.bmp') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('image/x-tga', '.tga') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('image/tiff', '.tiff') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('image/vnd.adobe.photoshop', '.psd') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('video/mp4', '.mp4') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('video/quicktime', '.mov') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('video/avi', '.avi') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('audio/mpeg', '.mp3') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('audio/m4a', '.m4a') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('audio/aac', '.aac') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('audio/ogg', '.ogg') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('audio/flac', '.flac') ./Telethon-1.37.0.tar.gz: Telethon-1.37.0/telethon/utils.py: mimetypes.add_type('application/x-tgsticker', '.tgs') ./webob-1.8.9.tar.gz: webob-1.8.9/src/webob/static.py: mimetypes.add_type('text/javascript', '.js') # stdlib default is application/x-javascript ./webob-1.8.9.tar.gz: webob-1.8.9/src/webob/static.py: mimetypes.add_type('image/x-icon', '.ico') # not among defaults ./webob-1.8.9.tar.gz: webob-1.8.9/tests/test_request.py: mimetypes.add_type('application/x-foo', '.foo') ./pyvo-1.6.tar.gz: pyvo-1.6/pyvo/dal/mimetype.py: mimetypes.add_type('application/fits', 'fits') ./pyvo-1.6.tar.gz: pyvo-1.6/pyvo/dal/mimetype.py: mimetypes.add_type('application/x-fits', 'fits') ./pyvo-1.6.tar.gz: pyvo-1.6/pyvo/dal/mimetype.py: mimetypes.add_type('image/fits', 'fits') ./pyvo-1.6.tar.gz: pyvo-1.6/pyvo/dal/mimetype.py: mimetypes.add_type('text/plain', 'txt') Time: 0:00:26.975038 Found 77 matching lines in 26 projects ```

    Of the 77 calls (in 26 projects) to mimetypes.add_type: