Repository: pypa/setuptools

Issue:
[BUG] New version 68.2.1 breaks `python setup.py --version` when using pyproject.toml
### setuptools version

setuptools==68.2.1

### Python version

Python 3.9.13

### OS

Mac OS X

### Additional environment information

_No response_

### Description

When using pyproject.toml's `[project]` descriptors's `version` attribute, the newest version of setup tools breaks with the following exception:

```
$ python setup.py --version
Traceback (most recent call last):
  File "/workspace/setup.py", line 2, in <module>
    setup(
  File "/Users/jstarker/.pyenv/versions/setup-version-failed/lib/python3.9/site-packages/setuptools/__init__.py", line 103, in setup
    return distutils.core.setup(**attrs)
  File "/Users/jstarker/.pyenv/versions/setup-version-failed/lib/python3.9/site-packages/setuptools/_distutils/core.py", line 172, in setup
    ok = dist.parse_command_line()
  File "/Users/jstarker/.pyenv/versions/setup-version-failed/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 467, in parse_command_line
    args = parser.getopt(args=self.script_args, object=self)
  File "/Users/jstarker/.pyenv/versions/setup-version-failed/lib/python3.9/site-packages/setuptools/_distutils/fancy_getopt.py", line 274, in getopt
    val = getattr(object, attr, 0) + 1
TypeError: can only concatenate str (not "int") to str
```


This works with `68.2.0`.

### Expected behavior

Expected to display the version of the test project

### How to Reproduce

1. Create two files:

```
# setup.py
from setuptools import setup
setup()
```

```
# pyproject.toml
[project]
name = "test"
version = "1.0.0"
```

2. Install `setuptools==68.2.1`
3. Run `python setup.py --version`

### Output

```console
$ python setup.py --version
Traceback (most recent call last):
  File "/workspace/setup.py", line 2, in <module>
    setup(
  File "/Users/jstarker/.pyenv/versions/setup-version-failed/lib/python3.9/site-packages/setuptools/__init__.py", line 103, in setup
    return distutils.core.setup(**attrs)
  File "/Users/jstarker/.pyenv/versions/setup-version-failed/lib/python3.9/site-packages/setuptools/_distutils/core.py", line 172, in setup
    ok = dist.parse_command_line()
  File "/Users/jstarker/.pyenv/versions/setup-version-failed/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 467, in parse_command_line
    args = parser.getopt(args=self.script_args, object=self)
  File "/Users/jstarker/.pyenv/versions/setup-version-failed/lib/python3.9/site-packages/setuptools/_distutils/fancy_getopt.py", line 274, in getopt
    val = getattr(object, attr, 0) + 1
TypeError: can only concatenate str (not "int") to str
```



Discussion:

Resolving patch:
diff --git a/setuptools/config/_apply_pyprojecttoml.py b/setuptools/config/_apply_pyprojecttoml.py
--- a/setuptools/config/_apply_pyprojecttoml.py
+++ b/setuptools/config/_apply_pyprojecttoml.py
@@ -125,7 +125,7 @@ def _set_config(dist: "Distribution", field: str, value: Any):
         setter(value)
     elif hasattr(dist.metadata, field) or field in SETUPTOOLS_PATCHES:
         setattr(dist.metadata, field, value)
-    if hasattr(dist, field):
+    else:
         setattr(dist, field, value)
 
 
@@ -212,12 +212,12 @@ def _dependencies(dist: "Distribution", val: list, _root_dir):
     if getattr(dist, "install_requires", []):
         msg = "`install_requires` overwritten in `pyproject.toml` (dependencies)"
         SetuptoolsWarning.emit(msg)
-    _set_config(dist, "install_requires", val)
+    dist.install_requires = val
 
 
 def _optional_dependencies(dist: "Distribution", val: dict, _root_dir):
     existing = getattr(dist, "extras_require", None) or {}
-    _set_config(dist, "extras_require", {**existing, **val})
+    dist.extras_require = {**existing, **val}
 
 
 def _unify_entry_points(project_table: dict):


Test patch:
diff --git a/setuptools/tests/config/test_apply_pyprojecttoml.py b/setuptools/tests/config/test_apply_pyprojecttoml.py
--- a/setuptools/tests/config/test_apply_pyprojecttoml.py
+++ b/setuptools/tests/config/test_apply_pyprojecttoml.py
@@ -423,6 +423,25 @@ def test_example_file_not_in_wheel(self, setuptools_wheel):
             assert not any(name.endswith(EXAMPLES_FILE) for name in zipfile.namelist())
 
 
+class TestInteropCommandLineParsing:
+    def test_version(self, tmp_path, monkeypatch, capsys):
+        # See pypa/setuptools#4047
+        # This test can be removed once the CLI interface of setup.py is removed
+        monkeypatch.chdir(tmp_path)
+        toml_config = """
+        [project]
+        name = "test"
+        version = "42.0"
+        """
+        pyproject = Path(tmp_path, "pyproject.toml")
+        pyproject.write_text(cleandoc(toml_config), encoding="utf-8")
+        opts = {"script_args": ["--version"]}
+        dist = pyprojecttoml.apply_configuration(Distribution(opts), pyproject)
+        dist.parse_command_line()  # <-- there should be no exception here.
+        captured = capsys.readouterr()
+        assert "42.0" in captured.out
+
+
 # --- Auxiliary Functions ---