44import hashlib
55import json
66import logging
7+ import typing
78from pathlib import Path
89
9- from . import model , tag , utils , jasyncio
10- from .url import URL
11- from .status import derive_status
10+ from . import jasyncio , model , tag , utils
1211from .annotationhelper import _get_annotations , _set_annotations
13- from .client import client
14- from .errors import JujuError , JujuApplicationConfigError
1512from .bundle import get_charm_series , is_local_charm
16- from .placement import parse as parse_placement
13+ from .client import client
14+ from .errors import JujuApplicationConfigError , JujuError
1715from .origin import Channel , Source
16+ from .placement import parse as parse_placement
17+ from .relation import Relation
18+ from .status import derive_status
19+ from .url import URL
20+ from .utils import block_until
1821
1922log = logging .getLogger (__name__ )
2023
@@ -59,14 +62,14 @@ def subordinate_units(self):
5962 return [u for u in self .units if u .is_subordinate ]
6063
6164 @property
62- def relations (self ):
65+ def relations (self ) -> typing . List [ Relation ] :
6366 return [rel for rel in self .model .relations if rel .matches (self .name )]
6467
6568 def related_applications (self , endpoint_name = None ):
6669 apps = {}
6770 for rel in self .relations :
6871 if rel .is_peer :
69- local_ep , remote_ep = rel .endpoints [ 0 ]
72+ local_ep , remote_ep = rel .endpoints
7073 else :
7174 def is_us (ep ):
7275 return ep .application .name == self .name
@@ -191,12 +194,13 @@ async def scale(self, scale=None, scale_change=None):
191194 scale_change = scale_change )
192195 ])
193196
194- async def destroy_relation (self , local_relation , remote_relation ):
197+ async def destroy_relation (self , local_relation , remote_relation , block_until_done : bool = False ):
195198 """Remove a relation to another application.
196199
197200 :param str local_relation: Name of relation on this application
198201 :param str remote_relation: Name of relation on the other
199202 application in the form '<application>[:<relation_name>]'
203+ :param bool block_until_done: Wait until the relation is completely removed.
200204
201205 """
202206 if ':' not in local_relation :
@@ -207,8 +211,16 @@ async def destroy_relation(self, local_relation, remote_relation):
207211 log .debug (
208212 'Destroying relation %s <-> %s' , local_relation , remote_relation )
209213
210- return await app_facade .DestroyRelation (endpoints = [
214+ await app_facade .DestroyRelation (endpoints = [
211215 local_relation , remote_relation ])
216+ if block_until_done :
217+ await block_until (
218+ lambda : not any (
219+ relation .matches (local_relation , remote_relation )
220+ for relation in self .relations
221+ )
222+ )
223+
212224 remove_relation = destroy_relation
213225
214226 async def destroy_unit (self , * unit_names ):
0 commit comments