Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept any non-string iterable for distutils.Extension's sources #311

Merged
merged 6 commits into from
Dec 27, 2024

Conversation

agriyakhetarpal
Copy link
Contributor

Description

This PR continues what was discussed in python/typeshed#12958 (comment) on allowing a loosened check for the source files for a distutils Extension instance.

Previously: just lists were accepted; now: any non-string iterable is accepted (tuples, sets, other iterators, etc.). I plan to update python/typeshed in accordance with this change.

Additional context

xref: python/mypy#18107, python/typeshed#12958

@agriyakhetarpal
Copy link
Contributor Author

I have a bunch of failing tests, linter errors, and several warnings from VS Code extensions locally; I hope the CI will be cleaner in its output. :)

.gitignore Outdated Show resolved Hide resolved
@agriyakhetarpal agriyakhetarpal force-pushed the types/extension-sources branch from e7aba2d to 115bb67 Compare November 6, 2024 22:02
Comment on lines 110 to 126
raise AssertionError("'name' must be a string") # noqa: TRY004
if not (
isinstance(sources, list)
and all(isinstance(v, (str, os.PathLike)) for v in sources)
):

# we handle the string case first; though strings are iterable, we disallow them
if isinstance(sources, str):
raise AssertionError( # noqa: TRY004
"'sources' must be an iterable of strings or PathLike objects, not a string"
)

# mow we check if it's iterable and contains valid types
try:
sources = list(sources) # convert to list for consistency
if not all(isinstance(v, (str, os.PathLike)) for v in sources):
raise AssertionError(
"All elements in 'sources' must be strings or PathLike objects"
)
except TypeError:
raise AssertionError(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question for the distutils maintainers: I can't help but feel that AssertionError is misused here, shouldn't these all be TypeError ? (it's noqa'd but not explained)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the same suggestion! :)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Peeking at the history, these used to be actual assert statements (7d70ca7), so my guess is that the AssertionErrors were kept for backwards compatibility with code that might try to catch these errors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, what I infer from the commit message is that that they were added because in-line assert statements are completely removed from the bytecode if used with -O

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect any Exception here is fine, so a TypeError should be fine (famous last words).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For uniformity, I changed the AssertionError for both the name and the sources checks in efeb97c to be a TypeError.

distutils/extension.py Outdated Show resolved Hide resolved
Co-Authored-By: Avasam <samuel.06@hotmail.com>
distutils/extension.py Outdated Show resolved Hide resolved
Co-authored-by: Avasam <samuel.06@hotmail.com>
@Avasam
Copy link
Contributor

Avasam commented Nov 6, 2024

To expand on the additional context: This allows typing the sources parameter in a way that avoids type invariance issues.
This indirectly relates to pypa/setuptools#2345 and pypa/setuptools#4689

distutils/extension.py Outdated Show resolved Hide resolved
distutils/extension.py Outdated Show resolved Hide resolved
agriyakhetarpal and others added 2 commits December 26, 2024 23:28
Co-authored-by: Jason R. Coombs <jaraco@jaraco.com>
Co-authored-by: Avasam <samuel.06@hotmail.com>
@jaraco jaraco merged commit b0aea96 into pypa:main Dec 27, 2024
@agriyakhetarpal agriyakhetarpal deleted the types/extension-sources branch December 27, 2024 03:27
Comment on lines +29 to +36
sources : Iterable[string | os.PathLike]
iterable of source filenames (except strings, which could be misinterpreted
as a single filename), relative to the distribution root (where the setup
script lives), in Unix form (slash-separated) for portability. Can be any
non-string iterable (list, tuple, set, etc.) containing strings or
PathLike objects. Source files may be C, C++, SWIG (.i), platform-specific
resource files, or whatever else is recognized by the "build_ext" command
as source for a Python extension.
Copy link
Contributor

@Avasam Avasam Jan 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized a possible inaccuracy: This documents instance attributes, not parameters. In which case the old docstring was (almost) correct. (sources is still a list[str], not a list[string | os.PathLike] because of os.fspath)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants