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

Overhaul pythonfinder #135

Merged
merged 27 commits into from
May 1, 2023
Merged

Overhaul pythonfinder #135

merged 27 commits into from
May 1, 2023

Conversation

matteius
Copy link
Contributor

Overhaul pythonfinder to use pydantic and eliminate the WindowsFinder code paths; remove attrs library.

In support of: pypa/pipenv#5670

Eliminating WindowsFinder and seeing all the tests pass for Windows in pipenv is a positive thing because not only does it drop the vendor requirement here, it also gets all the operating systems on the same code paths, so it should be easier to maintain going forward.

@matteius matteius requested a review from oz123 April 29, 2023 21:28
assert isinstance(parsed.version, Version)


@pytest.mark.skip_nt
def test_shims_are_kept(monkeypatch, no_pyenv_root_envvar, setup_pythons, no_virtual_env):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These two tests were really bad -- they use importlib to rejigger the import of the pydantic classes (reload them) but that has the side effect of re-registering the same validator method again with pydantic which raises a pydantic error. Further, these tests were asserting a lot of things about the mocks it had setup -- I feel they are not adequate tests and were already being skipped on windows for some reason.

@matteius
Copy link
Contributor Author

@finswimmer If you have some time to check out this as it pertains to: pypa/pipenv#5670

@finswimmer
Copy link
Contributor

Hey @matteius,

I'm not sure if it was intended to ping me here 😄 I don't have much knowledge about the internals of pythonfinder.

Overall I like the idea to switch to pydantic. (Actually this was something I have in mind as well when I first took some closer look at the codebase) 👍

What I saw so far is, that you are using type comments instead of type annotations. Because pythonfinder supports python >=3.7 only there is no need for type comments anymore. (See #130).

Also you should run pre-commit locally. This is not in the CI pipeline until now, because flake8 is throwing some errors, where I don't know how to fix them.

@oz123
Copy link
Contributor

oz123 commented Apr 30, 2023

What I saw so far is, that you are using type comments instead of type annotations. Because pythonfinder supports python >=3.7 only there is no need for type comments anymore. (See #130).

I believe these are just leftovers from the past. One can update these, but this should not be a blocker now.


def __str__(self) -> str:
return fs_str(f"{self.path.as_posix()}")
return fs_str("{0}".format(self.path.as_posix()))
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe fs_str can be removed, as well as compat.py. We these all over in vistir and reqlib.
Past issues with py2py3 version and unicode are now now history.

arch: str | None = None,
name: str | None = None,
) -> list[PathEntry]:
major=None, # type: Optional[Union[str, int]]
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason you used type comments and not type hints directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This PR came from I made and verified first in pipenv and then differed in from pipenv -- it seems master pythonfinder was ahead of what was in pipenv, but only in terms of type annotations. I corrected many of them, but I couldn't get to all of them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The other thing to note about some of the annotations is they weren't validating under all code paths because sometimes the types used in either a test or one of the paths is slightly different, so I had to loosen their types using Any for the time being. I figure there will be more iterating on this in the future, especially once pydantic 2 hits a stable release.

get_shim_paths,
)
from ..exceptions import InvalidPythonVersion
from ..utils import (
dedup,
Copy link
Contributor

Choose a reason for hiding this comment

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

Not an action item here, but I am writing this so we'll remember.
utils.py here contains common stuff with pipenv.
So maybe when we vendor this in pipenv we can remove it from pipenv.utils.
Also, dedup was dropped in favour of one liner.

@matteius matteius requested a review from oz123 April 30, 2023 14:43
@matteius
Copy link
Contributor Author

Thanks @finswimmer and @oz123 I addressed the PR feedback and Chat GPT helped me address the type hint method signatures.

@matteius
Copy link
Contributor Author

Also @finswimmer I did mean to tag you because of your recent work here -- this was my first time analyzing and updating the pythonfinder code base -- it took quite some time, but not as much as requirementslib is taking.

@oz123 oz123 merged commit 642642a into master May 1, 2023


class FinderBaseModel(BaseModel):
def __setattr__(self, name, value): # noqa: C901 (ignore complexity)
Copy link
Contributor

Choose a reason for hiding this comment

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

Hey @matteius,

could you explain to me why a custom implementation is needed for __setattr__ and how this implementation is different from the default behavior?

Thanks a lot!

fin swimmer

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pydantic has limitations about private variables (those prefixed with _) that they cannot be set/gotten or or returned in the dict -- I definitely needed it at one point in the refactor, it may be worth experimenting with if its still needed, or will be needed in pydantic 2.0, but I recall running into some initial errors that it got me past at that time.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for your quick response 👍

Not sure when you first implement this pattern. But I guess this is no longer needed, when setting underscore_attrs_are_private to True (https://docs.pydantic.dev/latest/usage/models/#private-model-attributes), right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're welcome to see if the tests pass in pipenv and this library by refactoring this work further -- I just wanted to get my feet wet in this library and have the larger goal of converting pipenv to a more modern framework.

@TBBle
Copy link

TBBle commented Mar 4, 2024

So just looking at using this library in another project, and it seems this commit removed PEP 514 support, but didn't update the docs to show that.

Python installs visible in py --list but not in the system PATH are not find by Pythonfinder 2.0.0 or later, but were visible with Pythonfinder <2.

@oz123
Copy link
Contributor

oz123 commented Mar 4, 2024

So just looking at using this library in another project, and it seems this commit removed PEP 514 support, but didn't update the docs to show that.

Python installs visible in py --list but not in the system PATH are not find by Pythonfinder 2.0.0 or later, but were visible with Pythonfinder <2.

Can you specify your OS and how you installed python?

@matteius
Copy link
Contributor Author

matteius commented Mar 4, 2024

@TBBle It was a feature (unknown to me at that time) of the windows library that was vendored in and providing the pythonfinder compatibility there, but it had other bugs; we wanted to unify the code base so that all OS flow through the same code path; there are some open issues in pipenv about this breaking as well and we are open to PRs that would directly add support for py command here in pythonfinder without using that other library for windows that we dropped.

@TBBle
Copy link

TBBle commented Mar 5, 2024

So just looking at using this library in another project, and it seems this commit removed PEP 514 support, but didn't update the docs to show that.
Python installs visible in py --list but not in the system PATH are not find by Pythonfinder 2.0.0 or later, but were visible with Pythonfinder <2.

Can you specify your OS and how you installed python?

I can open a full bug report later if you want, but trivially, this is Windows 11, with Python 3.9 and 3.10 installed as system installs using the official installer, and not added to the PATH. (Unless someone puts up a PR soon, I'd suggest removing PEP 514 from the feature list, as specifically PEP 514 support is what brought me to this tool.) (Edit: #158)

But the actual change I'm talking about is pretty clear, you can look at this PR and see that the PEP 514 library was removed, along with the only caller of PythonVersion.from_windows_launcher, and no registry access code nor library was added.

I guess that PEP 514 support had no unit test coverage, even though it was (and still is) listed on the features page, so this removal slipped under the radar. The current code-base still has no calls to PythonVersion.from_windows_launcher in it, from which I assume the feature wasn't intended to be removed.

I recommend not trying to wrap the py binary, as:

  • it'll be slower than directly implementing PEP 514, i.e. Windows registry access, as you're shelling out to a binary that is doing exactly that, as of Python 3.11's py.
  • py doesn't provide a machine-parsable output format, or any guarantee of output format stability.
  • The whole point of PEP 514 is to allow other tools to populate and access that same information without needing to rely on py even being installed, let alone shell out to it and parse its human-targeted output.

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