Skip to content

PYTHON-3867 add types to topology.py #1346

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 7 commits into from
Aug 9, 2023

Conversation

sleepyStick
Copy link
Contributor

@sleepyStick sleepyStick marked this pull request as ready for review August 8, 2023 18:13
@sleepyStick sleepyStick requested a review from a team as a code owner August 8, 2023 18:13
@sleepyStick sleepyStick requested review from NoahStapp and ShaneHarvey and removed request for a team August 8, 2023 18:13
@@ -1096,7 +1096,7 @@ def address(self) -> Optional[Tuple[str, int]]:
return self._server_property("address")

@property
def primary(self) -> Optional[Tuple[str, int]]:
def primary(self) -> Optional[_Address]:
Copy link
Member

Choose a reason for hiding this comment

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

Hmm this is a good catch but I'm not sure yet if it's correct. There's actually a subtle difference here between replica sets vs direct connections. In general, _Address can be have port=None because we support connecting directly to a single node via a unix socket path (which don't have ports). Here though we're returning addresses to replica set members which always have a port (I think?).

We should test or find out if unix paths can be used as replica set host names. This wouldn't be practical since it would require the replica set and clients to all live on the same machine but if it's possible I suppose we should make this change.

Copy link
Member

Choose a reason for hiding this comment

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

If you want to ignore this rabbit hole I suggest undoing the _Address changes in this PR and opening a new jira ticket.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hm I see, I open a new jira ticket for this then.

@@ -265,7 +265,7 @@ def test_nearest(self):

not_used = data_members.difference(used)
latencies = ", ".join(
"%s: %dms" % (server.description.address, server.description.round_trip_time)
"%s: %dms" % (server.description.address, server.description.round_trip_time) # type: ignore[str-format]
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to fix the format string to remove the type ignore?

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 believe the error is that round_trip_time is an Optional[float], my first instinct was to add an assert server.description.round_trip_time is not None statement but that doesn't work well with the list comprehension...alternatively, I could cast it? What are your thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

Can we use %s instead of %d?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes! good idea!

self._max_cluster_time = None
self._servers: Dict[_Address, Server] = {}
self._pid: Optional[int] = None
self._max_cluster_time: Optional[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.

Can we add a type alias for cluster time called ClusterTime?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

self._session_pool = _ServerSessionPool()

if self._publish_server or self._publish_tp:
weak: weakref.ReferenceType[Optional[queue.Queue]]
Copy link
Member

Choose a reason for hiding this comment

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

Should be ReferenceType[queue.Queue] (ditch the optional).

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 see now, fixed!

@@ -430,21 +475,22 @@ def _get_replica_set_members(self, selector):
):
return set()

return {sd.address for sd in selector(self._new_selection())}
# mypy doesn't recognize classes that implement a __getitem__ as something that is iterable
return {sd.address for sd in selector(self._new_selection())} # type: ignore[attr-defined]
Copy link
Member

Choose a reason for hiding this comment

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

Does calling iter() explicitly fix this: iter(selector(...))?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes! good idea!

@@ -1906,7 +1906,7 @@ def _send_cluster_time(
session_time = session.cluster_time if session else None
if topology_time and session_time:
if topology_time["clusterTime"] > session_time["clusterTime"]:
cluster_time = topology_time
cluster_time: Optional[Mapping[str, Any]] = topology_time
Copy link
Member

Choose a reason for hiding this comment

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

Let's use ClusterTime here too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good idea!

"""Return set of arbiter addresses."""
return self._get_replica_set_members(arbiter_server_selector)

def max_cluster_time(self):
def max_cluster_time(self) -> Optional[Mapping[str, Any]]:
Copy link
Member

Choose a reason for hiding this comment

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

Let's use ClusterTime here and anywhere else we use cluster_time or $clusterTime.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes! done!


def process_events_queue(queue_ref):

def process_events_queue(queue_ref: weakref.ReferenceType[Optional[queue.Queue]]) -> bool:
Copy link
Member

Choose a reason for hiding this comment

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

Ditch the optional here as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

right, sorry for missing it, thanks for catching that!

@@ -34,6 +34,7 @@
_Address = Tuple[str, Optional[int]]
_CollationIn = Union[Mapping[str, Any], "Collation"]
_Pipeline = Sequence[Mapping[str, Any]]
ClusterTime = Optional[Mapping[str, Any]]
Copy link
Member

Choose a reason for hiding this comment

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

Personally I think we should nix the Optional here.

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 don't have a huge preference either way, so its changed :)

@sleepyStick sleepyStick merged commit 34da931 into mongodb:master Aug 9, 2023
@sleepyStick sleepyStick deleted the PYTHON-3867 branch August 9, 2023 21:23
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