Skip to content

Conversation

@ghost
Copy link

@ghost ghost commented Jun 25, 2023

No description provided.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jun 25, 2023

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: francisbergin
Once this PR has been reviewed and has the lgtm label, please assign luap99 for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ghost ghost mentioned this pull request Jun 25, 2023
Copy link
Member

@jwhonce jwhonce left a comment

Choose a reason for hiding this comment

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

@francisbergin I like what I see on the whole. I am interested in what you find concerning the convenience methods. Changing delete() seems like an error in the type checker.

self,
path: Union[str, bytes],
params: Union[None, bytes, Mapping[str, str]] = None,
params: Union[None, bytes, Mapping[str, Any]] = None,
Copy link
Member

Choose a reason for hiding this comment

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

This change seems spurious as none of the other like methods were flagged, ie get/put/head/... These methods all call _request() which has params: Union[None, bytes, Mapping[str, str]] = None,

Copy link
Author

Choose a reason for hiding this comment

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

This change was to fix this error:

podman/domain/networks_manager.py:202: error: Dict entry 0 has incompatible type "str": "bool | None"; expected "str": "str"  [dict-item]

This is the call to delete in that file:

response = self.client.delete(f"/networks/{name}", params={"force": force})

Where force is typed Optional[bool].

Copy link
Author

Choose a reason for hiding this comment

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

So the type checker didn't flag the delete method directly; it flagged the call to it which did not follow the type hints.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, should the caller be fixed instead?

Copy link
Author

Choose a reason for hiding this comment

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

I think it is reasonable to call client.delete("...", params={"force": True} so supporting a bool value should be good.

However, I'm not sure the use of Mapping[str, Any] is the best approach. Since the value for params is sent directly to requests.Session.request, the most appropriate supported type would be that one. Typeshed defines it as:

_ParamsMappingKeyType: TypeAlias = str | bytes | int | float
_ParamsMappingValueType: TypeAlias = str | bytes | int | float | Iterable[str | bytes | int | float] | None
_Params: TypeAlias = (
    SupportsItems[_ParamsMappingKeyType, _ParamsMappingValueType]
    | tuple[_ParamsMappingKeyType, _ParamsMappingValueType]
    | Iterable[tuple[_ParamsMappingKeyType, _ParamsMappingValueType]]
    | str
    | bytes
)

But this seems like a lot. Also, if I understand correctly, using Any disables type verification for the specific variable.

Maybe we can just add support for bool to allow for the specific usage and adapt later as required?

params: Union[None, bytes, Mapping[str, Union[str, bool]]] = None,

Copy link
Member

Choose a reason for hiding this comment

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

I am comfortable with that change, as long as it is propagated to all the http verb helper functions, ie get/post/etc

Signed-off-by: Francis Bergin <francisbergin@hotmail.com>
@ghost
Copy link
Author

ghost commented Jul 9, 2023

@jwhonce The gating tests are now passing with type hint validation! However, I think this PR still needs a bit of work:

  • Careful review of a few code changes (I can create independent PRs for those)
  • #type: ignore[...] instances that could be removed with a bit of extra work
  • Any instances that could be replaced with more specific types
  • Using convention of list/dict/tuple or List/Dict/Tuple across package

There are a lot of changes required to get mypy to pass but I believe it brings a lot of value to the project.

Comment on lines +388 to +389
if isinstance(path, bytes):
path = path.decode()
Copy link
Author

Choose a reason for hiding this comment

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

@jwhonce Since path can be of type bytes, converting it to a string is required to get .lstrip(str) to be valid. Without conversion, a TypeError would be thrown on a bytes path. It seems all calls to APIClient are done within the package and all use strings for the path parameter. Is so, specifying path as str only would remove the need for a conversion here.

return self.name

@cached_property
@cached_property # type: ignore[operator]
Copy link
Author

Choose a reason for hiding this comment

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

For some reason, mypy thinks cached_property is a module and fails with a "module not callable" error.

Comment on lines +9 to +10
if TYPE_CHECKING:
from podman.domain.images_manager import ImagesManager
Copy link
Author

Choose a reason for hiding this comment

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

To avoid cyclic import.

Comment on lines -9 to +10
PodmanResourceType: TypeVar = TypeVar("PodmanResourceType", bound="PodmanResource")
# pylint: disable=invalid-name
PodmanResourceType = TypeVar("PodmanResourceType", bound="PodmanResource")
Copy link
Author

Choose a reason for hiding this comment

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

I'm not 100% confident in the PodmanResource/PodmanResourceType changes in this module.

Comment on lines -42 to +47
return self.manager.pull(repository, tag=self.id, platform=platform)
return self.manager.pull(repository[0], tag=self.id, platform=platform)
Copy link
Author

Choose a reason for hiding this comment

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

api.parse_repository returns a tuple but ImagesManager.pull takes a string as first argument.

Comment on lines -66 to +71
version = self.client.version()
version = self.client.version() # type: ignore[operator]
Copy link
Author

Choose a reason for hiding this comment

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

Here self.client is a APIClient where .version is a string. It would be in PodmanClient that .version would be callable. This specific line should throw an error as it is.

@umohnani8
Copy link
Member

@francisbergin any updates here?

@ghost
Copy link
Author

ghost commented Jan 22, 2024

Hi! No, I didn't have time to continue working on this. I still think it would be good to have but the PR still needs some work and I don't have much time now. Maybe another time!

@ghost ghost closed this Jan 22, 2024
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants