nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: pypa/setuptools
Pull request #4548 (2024-08-08 16:53:17)

Raise `TypeError` in `easy_install.CommandSpec.from_param`
## Summary of changes

Follow-up to https://github.com/pypa/setuptools/pull/4505#discussion_r1709867572 
As mentioned in that comment, let's include this PR in a major update since, although an edge case, isn't backwards compatible.

Changed the type of error raised by `setuptools.command.easy_install.CommandSpec.from_param` on unsupported argument from `AttributeError` to `TypeError`.

### Pull Request Checklist
- [x] Changes have tests
- [x] News fragment added in [`newsfragments/`].
  _(See [documentation][PR docs] for details)_

[`newsfragments/`]: https://github.com/pypa/setuptools/tree/master/newsfragments
[PR docs]:
https://setuptools.pypa.io/en/latest/development/developer-guide.html#making-a-pull-request


Avasam: > We can merge this once we are preparing a new major release.

Didn't make it to 73 ^^"



Patch:
diff --git a/newsfragments/4548.feature.rst b/newsfragments/4548.feature.rst
new file mode 100644
index 000000000..7fcf5f437
--- /dev/null
+++ b/newsfragments/4548.feature.rst
@@ -0,0 +1,1 @@
+Changed the type of error raised by ``setuptools.command.easy_install.CommandSpec.from_param`` on unsupported argument from `AttributeError` to `TypeError` -- by :user:`Avasam`
diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py
index 54d1e4844..2770a72b9 100644
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -2068,8 +2068,7 @@ class CommandSpec(list):
             return cls(param)
         if param is None:
             return cls.from_environment()
-        # AttributeError to keep backwards compatibility, this should really be a TypeError though
-        raise AttributeError(f"Argument has an unsupported type {type(param)}")
+        raise TypeError(f"Argument has an unsupported type {type(param)}")
 
     @classmethod
     def from_environment(cls):


Test patch:
diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py
index ca6af9667..de257db80 100644
--- a/setuptools/tests/test_easy_install.py
+++ b/setuptools/tests/test_easy_install.py
@@ -1332,6 +1332,16 @@ class TestCommandSpec:
         assert len(cmd) == 2
         assert '"' not in cmd.as_header()
 
+    def test_from_param_raises_expected_error(self) -> None:
+        """
+        from_param should raise its own TypeError when the argument's type is unsupported
+        """
+        with pytest.raises(TypeError) as exc_info:
+            ei.CommandSpec.from_param(object())  # type: ignore[arg-type] # We want a type error here
+        assert (
+            str(exc_info.value) == "Argument has an unsupported type <class 'object'>"
+        ), exc_info.value
+
 
 class TestWindowsScriptWriter:
     def test_header(self):
Repository: pypa/setuptools
Pull request #4576 (2024-08-19 20:14:43)

Sync with distutils@30b7331
- **Let _show_help() use commands instead of self.commands**
- **Enforce flake8-bugbear (B) and isort (I) ruff rules**
- **Add test capturing missed expectation.**
- **Ensure a missing target is still indicated as 'sources are newer' even when there are no sources.**

<!-- First time contributors: Take a moment to review https://setuptools.pypa.io/en/latest/development/developer-guide.html! -->
<!-- Remove sections if not applicable -->

## Summary of changes

<!-- Summary goes here -->

Style changes plus pypa/distutils#276 and pypa/distutils#284.

### Pull Request Checklist
- [x] Changes have tests
- [x] News fragment added in [`newsfragments/`].
  _(See [documentation][PR docs] for details)_


[`newsfragments/`]: https://github.com/pypa/setuptools/tree/master/newsfragments
[PR docs]:
https://setuptools.pypa.io/en/latest/development/developer-guide.html#making-a-pull-request



Patch:
diff --git a/newsfragments/+61911d95.bugfix.rst b/newsfragments/+61911d95.bugfix.rst
new file mode 100644
index 000000000..f542998cd
--- /dev/null
+++ b/newsfragments/+61911d95.bugfix.rst
@@ -0,0 +1,1 @@
+Synced with pypa/distutils@30b7331 including fix for modified check on empty sources (pypa/distutils#284).
\ No newline at end of file
diff --git a/setuptools/_distutils/_modified.py b/setuptools/_distutils/_modified.py
index 6532aa107..b7bdaa294 100644
--- a/setuptools/_distutils/_modified.py
+++ b/setuptools/_distutils/_modified.py
@@ -63,7 +63,7 @@ def newer_group(sources, target, missing='error'):
         return missing == 'newer' and not os.path.exists(source)
 
     ignored = os.path.exists if missing == 'ignore' else None
-    return any(
+    return not os.path.exists(target) or any(
         missing_as_newer(source) or _newer(source, target)
         for source in filter(ignored, sources)
     )
diff --git a/setuptools/_distutils/dist.py b/setuptools/_distutils/dist.py
index 0a57d60be..115302b3e 100644
--- a/setuptools/_distutils/dist.py
+++ b/setuptools/_distutils/dist.py
@@ -658,7 +658,7 @@ Common commands: (see '--help-commands' for more)
             )
             print()
 
-        for command in self.commands:
+        for command in commands:
             if isinstance(command, type) and issubclass(command, Command):
                 klass = command
             else:


Test patch:
diff --git a/setuptools/_distutils/tests/test_modified.py b/setuptools/_distutils/tests/test_modified.py
index 2bd82346c..e35cec2d6 100644
--- a/setuptools/_distutils/tests/test_modified.py
+++ b/setuptools/_distutils/tests/test_modified.py
@@ -117,3 +117,10 @@ def test_newer_pairwise_group(groups_target):
     newer = newer_pairwise_group([groups_target.newer], [groups_target.target])
     assert older == ([], [])
     assert newer == ([groups_target.newer], [groups_target.target])
+
+
+def test_newer_group_no_sources_no_target(tmp_path):
+    """
+    Consider no sources and no target "newer".
+    """
+    assert newer_group([], str(tmp_path / 'does-not-exist'))