We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
MissingParameterException when generating execution summary
Generating the execution summary may generate a MissingParameterException if a `requires` attempts to access a Config parameter which was specified only on the command line.

Example:

```python
# trouble.py
import luigi

class conf(luigi.Config):
    opt = luigi.Parameter()

class Root(luigi.WrapperTask):
    def requires(self):
        if conf().opt == 'A':
            return A()

class A(luigi.Task):
    def complete(self):
        return False

    def run(self):
        raise Exception()
```

```
$ luigi --module trouble Root --conf-opt=A
===== Luigi Execution Summary =====

Scheduled 2 tasks of which:
* 1 failed:
    - 1 A()
* 1 were left pending, among these:
    * 1 had failed dependencies:
        - 1 Root()

This progress looks :( because there were failed tasks

===== Luigi Execution Summary =====

Traceback (most recent call last):
  File "/opt/etl-virtualenv/bin/luigi", line 11, in <module>
    sys.exit(luigi_run())
  File "/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/cmdline.py", line 11, in luigi_run
    run_with_retcodes(argv)
  File "/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/retcodes.py", line 83, in run_with_retcodes
    task_sets = luigi.execution_summary._summary_dict(worker)
  File "/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/execution_summary.py", line 337, in _summary_dict
    _populate_unknown_statuses(set_tasks)
  File "/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/execution_summary.py", line 75, in _populate_unknown_statuses
    _depth_first_search(set_tasks, task, visited)
  File "/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/execution_summary.py", line 88, in _depth_first_search
    for task in current_task._requires():
  File "/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/task.py", line 607, in _requires
    return flatten(self.requires())  # base impl
  File "/private/tmp/trouble.py", line 8, in requires
    if conf().opt == 'A':
  File "/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/task_register.py", line 88, in __call__
    param_values = cls.get_param_values(params, args, kwargs)
  File "/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/task.py", line 412, in get_param_values
    raise parameter.MissingParameterException("%s: requires the '%s' parameter to be set" % (exc_desc, param_name))
luigi.parameter.MissingParameterException: conf[args=(), kwargs={}]: requires the 'opt' parameter to be set
```

This seems to be because the execution summary is generated outside any CmdlineParser context manager in run_with_retcodes. So this should be fairly easy to avoid by extending the entire run_with_retcodes to be within the CmdlineParser cm already there for the `retcode()` config - or if that could cause side effects I am unaware of then a separate context just for the call to _summary_dict.

I can attempt a PR for either approach.

May be related to #1964

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `luigi/retcodes.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright 2015-2015 Spotify AB
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17 """
18 Module containing the logic for exit codes for the luigi binary. It's useful
19 when you in a programmatic way need to know if luigi actually finished the
20 given task, and if not why.
21 """
22 
23 import luigi
24 import sys
25 import logging
26 from luigi import IntParameter
27 
28 
29 class retcode(luigi.Config):
30     """
31     See the :ref:`return codes configuration section <retcode-config>`.
32     """
33     # default value inconsistent with doc/configuration.rst for backwards compatibility reasons
34     unhandled_exception = IntParameter(default=4,
35                                        description='For internal luigi errors.',
36                                        )
37     # default value inconsistent with doc/configuration.rst for backwards compatibility reasons
38     missing_data = IntParameter(default=0,
39                                 description="For when there are incomplete ExternalTask dependencies.",
40                                 )
41     # default value inconsistent with doc/configuration.rst for backwards compatibility reasons
42     task_failed = IntParameter(default=0,
43                                description='''For when a task's run() method fails.''',
44                                )
45     # default value inconsistent with doc/configuration.rst for backwards compatibility reasons
46     already_running = IntParameter(default=0,
47                                    description='For both local --lock and luigid "lock"',
48                                    )
49     # default value inconsistent with doc/configuration.rst for backwards compatibility reasons
50     scheduling_error = IntParameter(default=0,
51                                     description='''For when a task's complete() or requires() fails,
52                                                    or task-limit reached'''
53                                     )
54     # default value inconsistent with doc/configuration.rst for backwards compatibility reasons
55     not_run = IntParameter(default=0,
56                            description="For when a task is not granted run permission by the scheduler."
57                            )
58 
59 
60 def run_with_retcodes(argv):
61     """
62     Run luigi with command line parsing, but raise ``SystemExit`` with the configured exit code.
63 
64     Note: Usually you use the luigi binary directly and don't call this function yourself.
65 
66     :param argv: Should (conceptually) be ``sys.argv[1:]``
67     """
68     logger = logging.getLogger('luigi-interface')
69     with luigi.cmdline_parser.CmdlineParser.global_instance(argv):
70         retcodes = retcode()
71 
72     worker = None
73     try:
74         worker = luigi.interface._run(argv)['worker']
75     except luigi.interface.PidLockAlreadyTakenExit:
76         sys.exit(retcodes.already_running)
77     except Exception:
78         # Some errors occur before logging is set up, we set it up now
79         luigi.interface.setup_interface_logging()
80         logger.exception("Uncaught exception in luigi")
81         sys.exit(retcodes.unhandled_exception)
82 
83     task_sets = luigi.execution_summary._summary_dict(worker)
84     root_task = luigi.execution_summary._root_task(worker)
85     non_empty_categories = {k: v for k, v in task_sets.items() if v}.keys()
86 
87     def has(status):
88         assert status in luigi.execution_summary._ORDERED_STATUSES
89         return status in non_empty_categories
90 
91     codes_and_conds = (
92         (retcodes.missing_data, has('still_pending_ext')),
93         (retcodes.task_failed, has('failed')),
94         (retcodes.already_running, has('run_by_other_worker')),
95         (retcodes.scheduling_error, has('scheduling_error')),
96         (retcodes.not_run, has('not_run')),
97     )
98     expected_ret_code = max(code * (1 if cond else 0) for code, cond in codes_and_conds)
99 
100     if expected_ret_code == 0 and \
101        root_task not in task_sets["completed"] and \
102        root_task not in task_sets["already_done"]:
103         sys.exit(retcodes.not_run)
104     else:
105         sys.exit(expected_ret_code)
106
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/luigi/retcodes.py b/luigi/retcodes.py
--- a/luigi/retcodes.py
+++ b/luigi/retcodes.py
@@ -80,9 +80,10 @@
         logger.exception("Uncaught exception in luigi")
         sys.exit(retcodes.unhandled_exception)
 
-    task_sets = luigi.execution_summary._summary_dict(worker)
-    root_task = luigi.execution_summary._root_task(worker)
-    non_empty_categories = {k: v for k, v in task_sets.items() if v}.keys()
+    with luigi.cmdline_parser.CmdlineParser.global_instance(argv):
+        task_sets = luigi.execution_summary._summary_dict(worker)
+        root_task = luigi.execution_summary._root_task(worker)
+        non_empty_categories = {k: v for k, v in task_sets.items() if v}.keys()
 
     def has(status):
         assert status in luigi.execution_summary._ORDERED_STATUSES

{"golden_diff": "diff --git a/luigi/retcodes.py b/luigi/retcodes.py\n--- a/luigi/retcodes.py\n+++ b/luigi/retcodes.py\n@@ -80,9 +80,10 @@\n         logger.exception(\"Uncaught exception in luigi\")\n         sys.exit(retcodes.unhandled_exception)\n \n-    task_sets = luigi.execution_summary._summary_dict(worker)\n-    root_task = luigi.execution_summary._root_task(worker)\n-    non_empty_categories = {k: v for k, v in task_sets.items() if v}.keys()\n+    with luigi.cmdline_parser.CmdlineParser.global_instance(argv):\n+        task_sets = luigi.execution_summary._summary_dict(worker)\n+        root_task = luigi.execution_summary._root_task(worker)\n+        non_empty_categories = {k: v for k, v in task_sets.items() if v}.keys()\n \n     def has(status):\n         assert status in luigi.execution_summary._ORDERED_STATUSES\n", "issue": "MissingParameterException when generating execution summary\nGenerating the execution summary may generate a MissingParameterException if a `requires` attempts to access a Config parameter which was specified only on the command line.\r\n\r\nExample:\r\n\r\n```python\r\n# trouble.py\r\nimport luigi\r\n\r\nclass conf(luigi.Config):\r\n    opt = luigi.Parameter()\r\n\r\nclass Root(luigi.WrapperTask):\r\n    def requires(self):\r\n        if conf().opt == 'A':\r\n            return A()\r\n\r\nclass A(luigi.Task):\r\n    def complete(self):\r\n        return False\r\n\r\n    def run(self):\r\n        raise Exception()\r\n```\r\n\r\n```\r\n$ luigi --module trouble Root --conf-opt=A\r\n===== Luigi Execution Summary =====\r\n\r\nScheduled 2 tasks of which:\r\n* 1 failed:\r\n    - 1 A()\r\n* 1 were left pending, among these:\r\n    * 1 had failed dependencies:\r\n        - 1 Root()\r\n\r\nThis progress looks :( because there were failed tasks\r\n\r\n===== Luigi Execution Summary =====\r\n\r\nTraceback (most recent call last):\r\n  File \"/opt/etl-virtualenv/bin/luigi\", line 11, in <module>\r\n    sys.exit(luigi_run())\r\n  File \"/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/cmdline.py\", line 11, in luigi_run\r\n    run_with_retcodes(argv)\r\n  File \"/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/retcodes.py\", line 83, in run_with_retcodes\r\n    task_sets = luigi.execution_summary._summary_dict(worker)\r\n  File \"/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/execution_summary.py\", line 337, in _summary_dict\r\n    _populate_unknown_statuses(set_tasks)\r\n  File \"/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/execution_summary.py\", line 75, in _populate_unknown_statuses\r\n    _depth_first_search(set_tasks, task, visited)\r\n  File \"/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/execution_summary.py\", line 88, in _depth_first_search\r\n    for task in current_task._requires():\r\n  File \"/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/task.py\", line 607, in _requires\r\n    return flatten(self.requires())  # base impl\r\n  File \"/private/tmp/trouble.py\", line 8, in requires\r\n    if conf().opt == 'A':\r\n  File \"/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/task_register.py\", line 88, in __call__\r\n    param_values = cls.get_param_values(params, args, kwargs)\r\n  File \"/opt/etl-virtualenv/lib/python3.6/site-packages/luigi/task.py\", line 412, in get_param_values\r\n    raise parameter.MissingParameterException(\"%s: requires the '%s' parameter to be set\" % (exc_desc, param_name))\r\nluigi.parameter.MissingParameterException: conf[args=(), kwargs={}]: requires the 'opt' parameter to be set\r\n```\r\n\r\nThis seems to be because the execution summary is generated outside any CmdlineParser context manager in run_with_retcodes. So this should be fairly easy to avoid by extending the entire run_with_retcodes to be within the CmdlineParser cm already there for the `retcode()` config - or if that could cause side effects I am unaware of then a separate context just for the call to _summary_dict.\r\n\r\nI can attempt a PR for either approach.\r\n\r\nMay be related to #1964\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n#\n# Copyright 2015-2015 Spotify AB\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\"\"\"\nModule containing the logic for exit codes for the luigi binary. It's useful\nwhen you in a programmatic way need to know if luigi actually finished the\ngiven task, and if not why.\n\"\"\"\n\nimport luigi\nimport sys\nimport logging\nfrom luigi import IntParameter\n\n\nclass retcode(luigi.Config):\n    \"\"\"\n    See the :ref:`return codes configuration section <retcode-config>`.\n    \"\"\"\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    unhandled_exception = IntParameter(default=4,\n                                       description='For internal luigi errors.',\n                                       )\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    missing_data = IntParameter(default=0,\n                                description=\"For when there are incomplete ExternalTask dependencies.\",\n                                )\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    task_failed = IntParameter(default=0,\n                               description='''For when a task's run() method fails.''',\n                               )\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    already_running = IntParameter(default=0,\n                                   description='For both local --lock and luigid \"lock\"',\n                                   )\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    scheduling_error = IntParameter(default=0,\n                                    description='''For when a task's complete() or requires() fails,\n                                                   or task-limit reached'''\n                                    )\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    not_run = IntParameter(default=0,\n                           description=\"For when a task is not granted run permission by the scheduler.\"\n                           )\n\n\ndef run_with_retcodes(argv):\n    \"\"\"\n    Run luigi with command line parsing, but raise ``SystemExit`` with the configured exit code.\n\n    Note: Usually you use the luigi binary directly and don't call this function yourself.\n\n    :param argv: Should (conceptually) be ``sys.argv[1:]``\n    \"\"\"\n    logger = logging.getLogger('luigi-interface')\n    with luigi.cmdline_parser.CmdlineParser.global_instance(argv):\n        retcodes = retcode()\n\n    worker = None\n    try:\n        worker = luigi.interface._run(argv)['worker']\n    except luigi.interface.PidLockAlreadyTakenExit:\n        sys.exit(retcodes.already_running)\n    except Exception:\n        # Some errors occur before logging is set up, we set it up now\n        luigi.interface.setup_interface_logging()\n        logger.exception(\"Uncaught exception in luigi\")\n        sys.exit(retcodes.unhandled_exception)\n\n    task_sets = luigi.execution_summary._summary_dict(worker)\n    root_task = luigi.execution_summary._root_task(worker)\n    non_empty_categories = {k: v for k, v in task_sets.items() if v}.keys()\n\n    def has(status):\n        assert status in luigi.execution_summary._ORDERED_STATUSES\n        return status in non_empty_categories\n\n    codes_and_conds = (\n        (retcodes.missing_data, has('still_pending_ext')),\n        (retcodes.task_failed, has('failed')),\n        (retcodes.already_running, has('run_by_other_worker')),\n        (retcodes.scheduling_error, has('scheduling_error')),\n        (retcodes.not_run, has('not_run')),\n    )\n    expected_ret_code = max(code * (1 if cond else 0) for code, cond in codes_and_conds)\n\n    if expected_ret_code == 0 and \\\n       root_task not in task_sets[\"completed\"] and \\\n       root_task not in task_sets[\"already_done\"]:\n        sys.exit(retcodes.not_run)\n    else:\n        sys.exit(expected_ret_code)\n", "path": "luigi/retcodes.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n#\n# Copyright 2015-2015 Spotify AB\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\"\"\"\nModule containing the logic for exit codes for the luigi binary. It's useful\nwhen you in a programmatic way need to know if luigi actually finished the\ngiven task, and if not why.\n\"\"\"\n\nimport luigi\nimport sys\nimport logging\nfrom luigi import IntParameter\n\n\nclass retcode(luigi.Config):\n    \"\"\"\n    See the :ref:`return codes configuration section <retcode-config>`.\n    \"\"\"\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    unhandled_exception = IntParameter(default=4,\n                                       description='For internal luigi errors.',\n                                       )\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    missing_data = IntParameter(default=0,\n                                description=\"For when there are incomplete ExternalTask dependencies.\",\n                                )\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    task_failed = IntParameter(default=0,\n                               description='''For when a task's run() method fails.''',\n                               )\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    already_running = IntParameter(default=0,\n                                   description='For both local --lock and luigid \"lock\"',\n                                   )\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    scheduling_error = IntParameter(default=0,\n                                    description='''For when a task's complete() or requires() fails,\n                                                   or task-limit reached'''\n                                    )\n    # default value inconsistent with doc/configuration.rst for backwards compatibility reasons\n    not_run = IntParameter(default=0,\n                           description=\"For when a task is not granted run permission by the scheduler.\"\n                           )\n\n\ndef run_with_retcodes(argv):\n    \"\"\"\n    Run luigi with command line parsing, but raise ``SystemExit`` with the configured exit code.\n\n    Note: Usually you use the luigi binary directly and don't call this function yourself.\n\n    :param argv: Should (conceptually) be ``sys.argv[1:]``\n    \"\"\"\n    logger = logging.getLogger('luigi-interface')\n    with luigi.cmdline_parser.CmdlineParser.global_instance(argv):\n        retcodes = retcode()\n\n    worker = None\n    try:\n        worker = luigi.interface._run(argv)['worker']\n    except luigi.interface.PidLockAlreadyTakenExit:\n        sys.exit(retcodes.already_running)\n    except Exception:\n        # Some errors occur before logging is set up, we set it up now\n        luigi.interface.setup_interface_logging()\n        logger.exception(\"Uncaught exception in luigi\")\n        sys.exit(retcodes.unhandled_exception)\n\n    with luigi.cmdline_parser.CmdlineParser.global_instance(argv):\n        task_sets = luigi.execution_summary._summary_dict(worker)\n        root_task = luigi.execution_summary._root_task(worker)\n        non_empty_categories = {k: v for k, v in task_sets.items() if v}.keys()\n\n    def has(status):\n        assert status in luigi.execution_summary._ORDERED_STATUSES\n        return status in non_empty_categories\n\n    codes_and_conds = (\n        (retcodes.missing_data, has('still_pending_ext')),\n        (retcodes.task_failed, has('failed')),\n        (retcodes.already_running, has('run_by_other_worker')),\n        (retcodes.scheduling_error, has('scheduling_error')),\n        (retcodes.not_run, has('not_run')),\n    )\n    expected_ret_code = max(code * (1 if cond else 0) for code, cond in codes_and_conds)\n\n    if expected_ret_code == 0 and \\\n       root_task not in task_sets[\"completed\"] and \\\n       root_task not in task_sets[\"already_done\"]:\n        sys.exit(retcodes.not_run)\n    else:\n        sys.exit(expected_ret_code)\n", "path": "luigi/retcodes.py"}]}