Skip to content

Tutor "dev launch" not compatible with latest click v8.3.0 #1276

@odemakov

Description

@odemakov

Bug description

Click 8.3.0 introduced a breaking change where optional parameters without defaults now receive a Sentinel object instead of None: pallets/click@b64ea07

This causes tutor dev launch to fail with a TypeError when building dev Docker images because the Sentinel object is passed to shlex.join(), which expects only string arguments.

/home/pupkin/tutor-19.0.5/. $ TUTOR_ROOT=$(pwd) tutor dev launch 
⚠️  Failed to enable plugin 'indigo': plugin 'indigo' is not installed.
⚠️  Failed to enable plugin 'mfe': plugin 'mfe' is not installed.
==================================================
        Interactive platform configuration
==================================================
As you are not running this platform in production, we automatically set the following configuration values:
    LMS_HOST = local.openedx.io
    CMS_HOST = studio.local.openedx.io
    ENABLE_HTTPS = False
Your platform name/title [My Open edX] 
Your public contact email address [contact@local.openedx.io] 
The default language code for the platform [en] 
Configuration saved to /home/pupkin/tutor-19.0.5/config.yml
Environment generated in /home/pupkin/tutor-19.0.5/env
======================================
        Building Docker images
======================================
Building image openedx-dev:19.0.5
Traceback (most recent call last):
  File "/home/pupkin/tutor-19.0.5/.venv/bin/tutor", line 7, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/tutor/commands/cli.py", line 27, in main
    cli()  # pylint: disable=no-value-for-parameter
    ^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/click/core.py", line 1462, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/click/core.py", line 1383, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/click/core.py", line 1850, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/click/core.py", line 1850, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/click/core.py", line 1246, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/click/core.py", line 814, in invoke
    return callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/click/decorators.py", line 34, in new_func
    return f(get_current_context(), *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/tutor/commands/compose.py", line 138, in launch
    context.invoke(images.build, image_names=images_to_build)
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/click/core.py", line 814, in invoke
    return callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/click/decorators.py", line 46, in new_func
    return f(get_current_context().obj, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/tutor/commands/images.py", line 241, in build
    images.build(
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/tutor/images.py", line 11, in build
    utils.docker(*command)
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/tutor/utils.py", line 193, in docker
    return execute("docker", *command)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/tutor-19.0.5/.venv/lib/python3.11/site-packages/tutor/utils.py", line 217, in execute
    click.echo(fmt.command(shlex.join(command)))
                           ^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/.pyenv/versions/3.11.8/lib/python3.11/shlex.py", line 320, in join
    return ' '.join(quote(arg) for arg in split_command)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pupkin/.pyenv/versions/3.11.8/lib/python3.11/shlex.py", line 320, in <genexpr>
    return ' '.join(quote(arg) for arg in split_command)
                    ^^^^^^^^^^
  File "/home/pupkin/.pyenv/versions/3.11.8/lib/python3.11/shlex.py", line 329, in quote
    if _find_unsafe(s) is None:
       ^^^^^^^^^^^^^^^
TypeError: expected string or bytes-like object, got 'Sentinel'

How to reproduce

  1. Set up Python environment:
    echo 3.11.8 > .python-version
    uv venv --python 3.11.8 .venv
    source .venv/bin/activate
  2. Install tutor:
    uv pip install "tutor==19.0.5"
  3. Run the failing command
    tutor dev launch

Environment

  • OS: MacOS Sequoia (also reproduced on Ubuntu)
  • Python: 3.11.8
  • Tutor: 19.0.5 and 20.0.1
  • Click: 8.3.0 (works fine with click <8.3.0)

Temporary fix

Install older version of click: uv pip install "click<8.3"

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBugs will be investigated and fixed as quickly as possible.

    Type

    No type

    Projects

    Status

    Blocked

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions