Skip to content

Commit ee6414e

Browse files
committed
chore: type hints for wait_for_idle specifically
1 parent a0fac06 commit ee6414e

1 file changed

Lines changed: 38 additions & 22 deletions

File tree

juju/model.py

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
from .annotationhelper import _get_annotations, _set_annotations
2929
from .bundle import BundleHandler, get_charm_series, is_local_charm
3030
from .charmhub import CharmHub
31-
from .client import client, connector
32-
from .client.connection import Connection
31+
from .client import client, connection, connector
3332
from .client.overrides import Caveat, Macaroon
3433
from .constraints import parse as parse_constraints
3534
from .controller import ConnectedController, Controller
@@ -60,6 +59,7 @@
6059

6160
if TYPE_CHECKING:
6261
from .application import Application
62+
from .client._definitions import FullStatus
6363
from .machine import Machine
6464
from .relation import Relation
6565
from .remoteapplication import ApplicationOffer, RemoteApplication
@@ -267,7 +267,9 @@ def apply_delta(self, delta):
267267
entity = self.get_entity(delta.entity, delta.get_id())
268268
return entity.previous(), entity
269269

270-
def get_entity(self, entity_type, entity_id, history_index=-1, connected=True):
270+
def get_entity(
271+
self, entity_type, entity_id, history_index=-1, connected=True
272+
) -> ModelEntity | None:
271273
"""Return an object instance for the given entity_type and id.
272274
273275
By default the object state matches the most recent state from
@@ -295,6 +297,11 @@ class ModelEntity:
295297
"""An object in the Model tree"""
296298

297299
entity_id: str
300+
model: Model
301+
_history_index: int
302+
connected: bool
303+
connection: connection.Connection
304+
_status: str
298305

299306
def __init__(
300307
self,
@@ -616,6 +623,9 @@ async def resolve(
616623
class Model:
617624
"""The main API for interacting with a Juju model."""
618625

626+
connector: connector.Connector
627+
state: ModelState
628+
619629
def __init__(
620630
self,
621631
max_frame_size=None,
@@ -660,7 +670,7 @@ def is_connected(self):
660670
"""Reports whether the Model is currently connected."""
661671
return self._connector.is_connected()
662672

663-
def connection(self) -> Connection:
673+
def connection(self) -> connection.Connection:
664674
"""Return the current Connection object. It raises an exception
665675
if the Model is disconnected
666676
"""
@@ -914,7 +924,10 @@ def add_local_charm(self, charm_file, series="", size=None):
914924
instead.
915925
916926
"""
917-
conn, headers, path_prefix = self.connection().https_connection()
927+
connection = self.connection()
928+
assert connection
929+
930+
conn, headers, path_prefix = connection.https_connection()
918931
path = "%s/charms?series=%s" % (path_prefix, series)
919932
headers["Content-Type"] = "application/zip"
920933
if size:
@@ -1212,11 +1225,12 @@ def name(self):
12121225
return self._info.name
12131226

12141227
@property
1215-
def info(self):
1228+
def info(self) -> ModelInfo:
12161229
"""Return the cached client.ModelInfo object for this Model.
12171230
12181231
If Model.get_info() has not been called, this will return None.
12191232
"""
1233+
assert self._info is not None
12201234
return self._info
12211235

12221236
@property
@@ -1306,11 +1320,13 @@ async def _all_watcher():
13061320
del allwatcher.Id
13071321
continue
13081322
except websockets.ConnectionClosed:
1309-
monitor = self.connection().monitor
1323+
connection = self.connection()
1324+
assert connection
1325+
monitor = connection.monitor
13101326
if monitor.status == monitor.ERROR:
13111327
# closed unexpectedly, try to reopen
13121328
log.warning("Watcher: connection closed, reopening")
1313-
await self.connection().reconnect()
1329+
await connection.reconnect()
13141330
if monitor.status != monitor.CONNECTED:
13151331
# reconnect failed; abort and shutdown
13161332
log.error(
@@ -2624,7 +2640,7 @@ async def get_action_status(self, uuid_or_prefix=None, name=None):
26242640
results[tag.untag("action-", a.action.tag)] = a.status
26252641
return results
26262642

2627-
async def get_status(self, filters=None, utc=False):
2643+
async def get_status(self, filters=None, utc=False) -> FullStatus:
26282644
"""Return the status of the model.
26292645
26302646
:param str filters: Optional list of applications, units, or machines
@@ -2959,15 +2975,15 @@ async def _get_source_api(self, url):
29592975
async def wait_for_idle(
29602976
self,
29612977
apps: list[str] | None = None,
2962-
raise_on_error=True,
2963-
raise_on_blocked=False,
2964-
wait_for_active=False,
2965-
timeout=10 * 60,
2966-
idle_period=15,
2967-
check_freq=0.5,
2968-
status=None,
2969-
wait_for_at_least_units=None,
2970-
wait_for_exact_units=None,
2978+
raise_on_error: bool = True,
2979+
raise_on_blocked: bool = False,
2980+
wait_for_active: bool = False,
2981+
timeout: float | None = 10 * 60,
2982+
idle_period: float = 15,
2983+
check_freq: float = 0.5,
2984+
status: str | None = None,
2985+
wait_for_at_least_units: int | None = None,
2986+
wait_for_exact_units: int | None = None,
29712987
) -> None:
29722988
"""Wait for applications in the model to settle into an idle state.
29732989
@@ -3035,12 +3051,12 @@ async def wait_for_idle(
30353051
raise JujuError(f"Expected a List[str] for apps, given {apps}")
30363052

30373053
apps = apps or self.applications
3038-
idle_times = {}
3039-
units_ready = set() # The units that are in the desired state
3040-
last_log_time = None
3054+
idle_times: dict[str, datetime] = {}
3055+
units_ready: set[str] = set() # The units that are in the desired state
3056+
last_log_time: datetime | None = None
30413057
log_interval = timedelta(seconds=30)
30423058

3043-
def _raise_for_status(entities, status):
3059+
def _raise_for_status(entities: dict[str, list[str]], status: Any):
30443060
if not entities:
30453061
return
30463062
for entity_name, error_type in (

0 commit comments

Comments
 (0)