Repository: dbt-labs/dbt-core
Pull request: fix constructing param with 0 value
resolves #8297
[docs](https://github.com/dbt-labs/docs.getdbt.com/issues/new/choose) dbt-labs/docs.getdbt.com/#  

<!---
  Include the number of the issue addressed by this PR above if applicable.
  PRs for code changes without an associated issue *will not be merged*.
  See CONTRIBUTING.md for more information.

  Include the number of the docs issue that was opened for this PR. If
  this change has no user-facing implications, "N/A" suffices instead. New
  docs tickets can be created by clicking the link above or by going to
  https://github.com/dbt-labs/docs.getdbt.com/issues/new/choose.
-->

### Problem

<!---
  Describe the problem this PR is solving. What is the application state
  before this PR is merged?
-->

### Solution

<!---
  Describe the way this PR solves the above problem. Add as much detail as you
  can to help reviewers understand your changes. Include any alternatives and
  tradeoffs you considered.
-->

### Checklist

- [x] I have read [the contributing guide](https://github.com/dbt-labs/dbt-core/blob/main/CONTRIBUTING.md) and understand what's expected of me  
- [x] I have run this code in development and it appears to resolve the stated issue  
- [x] This PR includes tests, or tests are not required/relevant for this PR
- [x] This PR has no interface changes (e.g. macros, cli, logs, json artifacts, config files, adapter interface, etc) or this PR has already received feedback and approval from Product or DX


Problem statement:
[CT-2924] [Bug] Retry does not construct flags properly for 0 valued parameter
### Is this a new bug in dbt-core?

- [X] I believe this is a new bug in dbt-core
- [X] I have searched the existing issues, and I could not find an existing issue for this bug

### Current Behavior

Retry would fail if previous command run with `--log-file-max-bytes 0` specified.

### Expected Behavior

Retry properly get the behavior of `--log-file-max-bytes 0`

### Steps To Reproduce

1. In a dbt project, run `dbt --log-file-max-bytes 0 run`.
2. run `dbt retry`

### Relevant log output

```shell
20:12:53  Running with dbt=1.6.0
20:12:53  Registered adapter: postgres=1.6.0
20:12:53  Encountered an error:
No such option: --no-log-file-max-bytes
20:12:53  Traceback (most recent call last):
  File "/Users/chenyuli/git/dbt-core/core/dbt/cli/requires.py", line 87, in wrapper
    result, success = func(*args, **kwargs)
                      ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/dbt-core/core/dbt/cli/requires.py", line 72, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/dbt-core/core/dbt/cli/requires.py", line 143, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/dbt-core/core/dbt/cli/requires.py", line 172, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/dbt-core/core/dbt/cli/requires.py", line 219, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/dbt-core/core/dbt/cli/requires.py", line 259, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/dbt-core/core/dbt/cli/main.py", line 608, in retry
    results = task.run()
              ^^^^^^^^^^
  File "/Users/chenyuli/git/dbt-core/core/dbt/task/retry.py", line 94, in run
    retry_flags = Flags.from_dict(cli_command, self.previous_args)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/dbt-core/core/dbt/cli/flags.py", line 294, in from_dict
    ctx = args_to_context(command_arg_list)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/dbt-core/core/dbt/cli/flags.py", line 59, in args_to_context
    cli_ctx = cli.make_context(cli.name, args)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/ide-server/ide-server/lib/python3.11/site-packages/click/core.py", line 920, in make_context
    self.parse_args(ctx, args)
  File "/Users/chenyuli/git/ide-server/ide-server/lib/python3.11/site-packages/click/core.py", line 1613, in parse_args
    rest = super().parse_args(ctx, args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/ide-server/ide-server/lib/python3.11/site-packages/click/core.py", line 1375, in parse_args
    opts, args, param_order = parser.parse_args(args=args)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/chenyuli/git/ide-server/ide-server/lib/python3.11/site-packages/click/parser.py", line 337, in parse_args
    self._process_args_for_options(state)
  File "/Users/chenyuli/git/ide-server/ide-server/lib/python3.11/site-packages/click/parser.py", line 364, in _process_args_for_options
    self._process_opts(arg, state)
  File "/Users/chenyuli/git/ide-server/ide-server/lib/python3.11/site-packages/click/parser.py", line 514, in _process_opts
    self._match_long_opt(norm_long_opt, explicit_value, state)
  File "/Users/chenyuli/git/ide-server/ide-server/lib/python3.11/site-packages/click/parser.py", line 398, in _match_long_opt
    raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx)
click.exceptions.NoSuchOption: No such option: --no-log-file-max-bytes
```

Hints from issue discussion:

Commit message: fix constructing param with 0 value

Patch to review:
diff --git a/.changes/unreleased/Fixes-20230802-141556.yaml b/.changes/unreleased/Fixes-20230802-141556.yaml
new file mode 100644
index 00000000000..8b96ccab5c7
--- /dev/null
+++ b/.changes/unreleased/Fixes-20230802-141556.yaml
@@ -0,0 +1,6 @@
+kind: Fixes
+body: Fix retry not working with log-file-max-bytes
+time: 2023-08-02T14:15:56.306027-07:00
+custom:
+  Author: ChenyuLInx
+  Issue: "8297"
diff --git a/core/dbt/cli/flags.py b/core/dbt/cli/flags.py
index df79ad5941b..8a60eae208b 100644
--- a/core/dbt/cli/flags.py
+++ b/core/dbt/cli/flags.py
@@ -61,7 +61,6 @@ def args_to_context(args: List[str]) -> Context:
     if len(args) == 1 and "," in args[0]:
         args = args[0].split(",")
     sub_command_name, sub_command, args = cli.resolve_command(cli_ctx, args)
-
     # Handle source and docs group.
     if isinstance(sub_command, Group):
         sub_command_name, sub_command, args = sub_command.resolve_command(cli_ctx, args)
@@ -319,7 +318,6 @@ def command_params(command: CliCommand, args_dict: Dict[str, Any]) -> CommandPar
 
     for k, v in args_dict.items():
         k = k.lower()
-
         # if a "which" value exists in the args dict, it should match the command provided
         if k == WHICH_KEY:
             if v != command.value:
@@ -344,7 +342,8 @@ def add_fn(x):
 
         if k == "macro" and command == CliCommand.RUN_OPERATION:
             add_fn(v)
-        elif v in (None, False):
+        # None is Signletons, False is flyweight, only one instance of each.
+        elif v is None or v is False:
             add_fn(f"--no-{spinal_cased}")
         elif v is True:
             add_fn(f"--{spinal_cased}")
diff --git a/tests/unit/test_cli_flags.py b/tests/unit/test_cli_flags.py
index 8ff85dc144c..d5d78a229ae 100644
--- a/tests/unit/test_cli_flags.py
+++ b/tests/unit/test_cli_flags.py
@@ -391,3 +391,8 @@ def test_from_dict__which_fails(self):
         args_dict = {"which": "some bad command"}
         with pytest.raises(DbtInternalError, match=r"does not match value of which"):
             self._create_flags_from_dict(Command.RUN, args_dict)
+
+    def test_from_dict_0_value(self):
+        args_dict = {"log_file_max_bytes": 0}
+        flags = Flags.from_dict(Command.RUN, args_dict)
+        assert flags.LOG_FILE_MAX_BYTES == 0


Code review comments:
diff_hunk: @@ -344,7 +342,8 @@ def add_fn(x):
 
         if k == "macro" and command == CliCommand.RUN_OPERATION:
             add_fn(v)
-        elif v in (None, False):
+        # None is Signletons, False is flyweight, only one instance of each.
path: core/dbt/cli/flags.py
text: @user1:
Nit: Singleton is misspelled.

Here's one way it could be rewritten slightly:

```suggestion
        # None is a Singleton, False is a Flyweight, only one instance of each.
```

@author:
I blame it on copilot LOL