Skip to content

Type setuptools/msvc.py dir methods and properties #4755

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

Merged
merged 2 commits into from
May 28, 2025

Conversation

Avasam
Copy link
Contributor

@Avasam Avasam commented Nov 20, 2024

Summary of changes

Extracted from #4744 with additional fixes

Pull Request Checklist

Comment on lines 719 to 724
return sdkdir or ''
return sdkdir

return None
return ''
Copy link
Contributor Author

@Avasam Avasam Nov 20, 2024

Choose a reason for hiding this comment

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

This one I'm not entirely certain of, and does change the possible return types.

dir-related properties of this class are a mixed bag on whether they return None or '' as a fallthrough case. And are almost never documented as returning None (which is fixed in this PR).

However all other properties that can return None are checked for truthiness when used, this one isn't. (hence it was causing issues for #4744)

The redundant or '' makes me think this may have been intended to not return None. But the true intention is unclear to me.


After further research, it was auto-added here as an explicit return: https://github.com/pypa/setuptools/pull/4169/files#diff-2f10e0b183f00587feb575c7716d38f4951d4f7ded5b714396e96066ae7254bdR953

Now I'm pretty sure that the original intention was to return a '' by default. But that means maybe other methods as well ?

Anyway, if you think this should return None by default, I'll add checks to the methods that use this property instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you very much for having a look on this.

It is a complicated decision. For the sake of backwards compatibility I think a safe approach would be to stick with the observed behaviour instead of the original intention?

Even if return None was a late automatic addition, the original function could still returning None under certain circumstances isn't it? So it may be safer for us to accept it can return None?

Copy link
Contributor Author

@Avasam Avasam May 23, 2025

Choose a reason for hiding this comment

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

8ff634c (#4755) Shows the diff letting this return None.

Same resolved TypeError in UniversalCRTSdkLastVersion, UCRTLibraries, UCRTIncludes and their caller when UniversalCRTSdkDir returns None.
If you want these to also keep the exact same exception raising behaviour, I can raise an explicit TypeError in them.

Copy link
Contributor

@abravalheri abravalheri May 23, 2025

Choose a reason for hiding this comment

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

Thank you. I think it may make sense to keep the behaviour.

Do the type checkers allow something like the following?

try:
    ...
except TypeError as ex:
    py310.add_note(ex, "Cannot find UniversalCRTSdkDir")
    raise

(py310 => from .compat import py310)

Copy link
Contributor Author

@Avasam Avasam May 23, 2025

Choose a reason for hiding this comment

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

Python's type system does not propagate possible exceptions to be raised.
No type-checkers that I know of special-cases try-except either.

So no, type-checkers, won't know to silence an issue if you catch a TypeError.

It'd look more like this:

  	if (UniversalCRTSdkDir := self.UniversalCRTSdkDir) is None:
        raise TypeError("Cannot find UniversalCRTSdkDir")
    return self._use_last_dir_name(os.path.join(UniversalCRTSdkDir, 'lib'))

or

    try:
        return self._use_last_dir_name(
            os.path.join(self.UniversalCRTSdkDir, 'lib')  # type: ignore[arg-type] # Expected TypeError
        )
    except TypeError as ex:
        py310.add_note(ex, "Cannot find UniversalCRTSdkDir")
        raise

without the additional note:

    return self._use_last_dir_name(
        # Let TypeError bubble up when UniversalCRTSdkDir is None for backwards compatibility
        os.path.join(self.UniversalCRTSdkDir, 'lib')  # type: ignore[arg-type]
    )

All 3 options above preserve the behaviour of raising a TypeError because of a None UniversalCRTSdkDir

Copy link
Contributor

Choose a reason for hiding this comment

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

I am more inclined towards the 2nd option for being the balance between leaving things as they are and providing debugging information if necessary.

@Avasam Avasam force-pushed the type-msvc-dir-methods-and-properties branch 2 times, most recently from 5ab8346 to 6ad33ba Compare November 24, 2024 22:53
@Avasam Avasam mentioned this pull request Dec 23, 2024
2 tasks
@Avasam Avasam force-pushed the type-msvc-dir-methods-and-properties branch 3 times, most recently from 0fa9594 to 9d79a59 Compare January 6, 2025 05:16
@Avasam Avasam force-pushed the type-msvc-dir-methods-and-properties branch from 9d79a59 to 2185ae9 Compare January 21, 2025 00:17
@Avasam Avasam force-pushed the type-msvc-dir-methods-and-properties branch from 2185ae9 to 7fc946a Compare May 3, 2025 14:01
@Avasam Avasam force-pushed the type-msvc-dir-methods-and-properties branch from 7fc946a to 1e0fa31 Compare May 15, 2025 16:19
@Avasam Avasam force-pushed the type-msvc-dir-methods-and-properties branch 4 times, most recently from 50880f0 to 8ff634c Compare May 23, 2025 16:10
path
"""
sdkdir = ''
sdkdir: str | None = ''
for ver in self.NetFxSdkVersion:
loc = os.path.join(self.ri.netfx_sdk, ver)
sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder')
Copy link
Contributor Author

@Avasam Avasam May 23, 2025

Choose a reason for hiding this comment

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

Because RegistryInfo.lookup can return None, and this method returns the last falsy result if all falsy. Then the return type is potentially None. (which will happen if no kitsinstallationfolder value is found)

@Avasam Avasam force-pushed the type-msvc-dir-methods-and-properties branch from 106287a to d971dd7 Compare May 27, 2025 15:18
@Avasam Avasam force-pushed the type-msvc-dir-methods-and-properties branch from d971dd7 to 0510646 Compare May 27, 2025 15:25
Co-authored-by: Anderson Bravalheri <andersonbravalheri+github@gmail.com>
Copy link
Contributor

@abravalheri abravalheri left a comment

Choose a reason for hiding this comment

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

Thank you very much!

@abravalheri abravalheri merged commit f9bf422 into pypa:main May 28, 2025
20 of 24 checks passed
@Avasam Avasam deleted the type-msvc-dir-methods-and-properties branch May 28, 2025 14:22
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.

2 participants