Skip to content

Commit 4626033

Browse files
committed
Remove is_dict,is_str for better pyright inference
When support for python3.8 and python3.9 has been dropped, it will be possible to eat the cak and have it due to PEP-647. Signed-off-by: legobt <[email protected]>
1 parent fc90f60 commit 4626033

File tree

1 file changed

+51
-53
lines changed

1 file changed

+51
-53
lines changed

podman_compose.py

Lines changed: 51 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,12 @@
4242
# helper functions
4343

4444

45-
def is_str(string_object):
46-
return isinstance(string_object, str)
47-
48-
49-
def is_dict(dict_object):
50-
return isinstance(dict_object, dict)
51-
52-
5345
def is_list(list_object):
54-
return not is_str(list_object) and not is_dict(list_object) and hasattr(list_object, "__iter__")
46+
return (
47+
not isinstance(list_object, str)
48+
and not isinstance(list_object, dict)
49+
and hasattr(list_object, "__iter__")
50+
)
5551

5652

5753
# identity filter
@@ -263,8 +259,8 @@ def rec_subs(value, subs_dict):
263259
"""
264260
do bash-like substitution in value and if list of dictionary do that recursively
265261
"""
266-
if is_dict(value):
267-
if 'environment' in value and is_dict(value['environment']):
262+
if isinstance(value, dict):
263+
if 'environment' in value and isinstance(value['environment'], dict):
268264
# Load service's environment variables
269265
subs_dict = subs_dict.copy()
270266
svc_envs = {k: v for k, v in value['environment'].items() if k not in subs_dict}
@@ -275,7 +271,7 @@ def rec_subs(value, subs_dict):
275271
subs_dict.update(svc_envs)
276272

277273
value = {k: rec_subs(v, subs_dict) for k, v in value.items()}
278-
elif is_str(value):
274+
elif isinstance(value, str):
279275

280276
def convert(m):
281277
if m.group("escaped") is not None:
@@ -303,7 +299,7 @@ def norm_as_list(src):
303299
"""
304300
if src is None:
305301
dst = []
306-
elif is_dict(src):
302+
elif isinstance(src, dict):
307303
dst = [(f"{k}={v}" if v is not None else k) for k, v in src.items()]
308304
elif is_list(src):
309305
dst = list(src)
@@ -319,13 +315,13 @@ def norm_as_dict(src):
319315
"""
320316
if src is None:
321317
dst = {}
322-
elif is_dict(src):
318+
elif isinstance(src, dict):
323319
dst = dict(src)
324320
elif is_list(src):
325321
dst = [i.split("=", 1) for i in src if i]
326322
dst = [(a if len(a) == 2 else (a[0], None)) for a in dst]
327323
dst = dict(dst)
328-
elif is_str(src):
324+
elif isinstance(src, str):
329325
key, value = src.split("=", 1) if "=" in src else (src, None)
330326
dst = {key: value}
331327
else:
@@ -334,7 +330,7 @@ def norm_as_dict(src):
334330

335331

336332
def norm_ulimit(inner_value):
337-
if is_dict(inner_value):
333+
if isinstance(inner_value, dict):
338334
if not inner_value.keys() & {"soft", "hard"}:
339335
raise ValueError("expected at least one soft or hard limit")
340336
soft = inner_value.get("soft", inner_value.get("hard", None))
@@ -468,7 +464,7 @@ def mount_desc_to_mount_args(compose, mount_desc, srv_name, cnt_name): # pylint
468464
def ulimit_to_ulimit_args(ulimit, podman_args):
469465
if ulimit is not None:
470466
# ulimit can be a single value, i.e. ulimit: host
471-
if is_str(ulimit):
467+
if isinstance(ulimit, str):
472468
podman_args.extend(["--ulimit", ulimit])
473469
# or a dictionary or list:
474470
else:
@@ -535,7 +531,7 @@ def mount_desc_to_volume_args(compose, mount_desc, srv_name, cnt_name): # pylin
535531
def get_mnt_dict(compose, cnt, volume):
536532
srv_name = cnt["_service"]
537533
basedir = compose.dirname
538-
if is_str(volume):
534+
if isinstance(volume, str):
539535
volume = parse_short_mount(volume, basedir)
540536
return fix_mount_dict(compose, volume, srv_name)
541537

@@ -571,7 +567,7 @@ def get_secret_args(compose, cnt, secret, podman_is_building=False):
571567
podman_is_building: True if we are preparing arguments for an invocation of "podman build"
572568
False if we are preparing for something else like "podman run"
573569
"""
574-
secret_name = secret if is_str(secret) else secret.get("source", None)
570+
secret_name = secret if isinstance(secret, str) else secret.get("source", None)
575571
if not secret_name or secret_name not in compose.declared_secrets.keys():
576572
raise ValueError(f'ERROR: undeclared secret: "{secret}", service: {cnt["_service"]}')
577573
declared_secret = compose.declared_secrets[secret_name]
@@ -580,11 +576,11 @@ def get_secret_args(compose, cnt, secret, podman_is_building=False):
580576
dest_file = ""
581577
secret_opts = ""
582578

583-
secret_target = None if is_str(secret) else secret.get("target", None)
584-
secret_uid = None if is_str(secret) else secret.get("uid", None)
585-
secret_gid = None if is_str(secret) else secret.get("gid", None)
586-
secret_mode = None if is_str(secret) else secret.get("mode", None)
587-
secret_type = None if is_str(secret) else secret.get("type", None)
579+
secret_target = None if isinstance(secret, str) else secret.get("target", None)
580+
secret_uid = None if isinstance(secret, str) else secret.get("uid", None)
581+
secret_gid = None if isinstance(secret, str) else secret.get("gid", None)
582+
secret_mode = None if isinstance(secret, str) else secret.get("mode", None)
583+
secret_type = None if isinstance(secret, str) else secret.get("type", None)
588584

589585
if source_file:
590586
# assemble path for source file first, because we need it for all cases
@@ -827,7 +823,7 @@ def get_network_create_args(net_desc, proj_name, net_name):
827823
if net_desc.get("enable_ipv6", None):
828824
args.append("--ipv6")
829825

830-
if is_dict(ipam_config_ls):
826+
if isinstance(ipam_config_ls, dict):
831827
ipam_config_ls = [ipam_config_ls]
832828
for ipam_config in ipam_config_ls:
833829
subnet = ipam_config.get("subnet", None)
@@ -852,13 +848,13 @@ async def assert_cnt_nets(compose, cnt):
852848
if net and not net.startswith("bridge"):
853849
return
854850
cnt_nets = cnt.get("networks", None)
855-
if cnt_nets and is_dict(cnt_nets):
851+
if cnt_nets and isinstance(cnt_nets, dict):
856852
cnt_nets = list(cnt_nets.keys())
857853
cnt_nets = norm_as_list(cnt_nets or compose.default_net)
858854
for net in cnt_nets:
859855
net_desc = compose.networks[net] or {}
860856
is_ext = net_desc.get("external", None)
861-
ext_desc = is_ext if is_dict(is_ext) else {}
857+
ext_desc = is_ext if isinstance(is_ext, dict) else {}
862858
default_net_name = default_network_name_for_project(compose, net, is_ext)
863859
net_name = ext_desc.get("name", None) or net_desc.get("name", None) or default_net_name
864860
try:
@@ -917,7 +913,7 @@ def get_net_args(compose, cnt):
917913
ip_assignments = 0
918914
if cnt.get("_aliases", None):
919915
aliases.extend(cnt.get("_aliases", None))
920-
if cnt_nets and is_dict(cnt_nets):
916+
if cnt_nets and isinstance(cnt_nets, dict):
921917
prioritized_cnt_nets = []
922918
# cnt_nets is {net_key: net_value, ...}
923919
for net_key, net_value in cnt_nets.items():
@@ -945,7 +941,7 @@ def get_net_args(compose, cnt):
945941
for net in cnt_nets:
946942
net_desc = compose.networks[net] or {}
947943
is_ext = net_desc.get("external", None)
948-
ext_desc = is_ext if is_dict(is_ext) else {}
944+
ext_desc = is_ext if isinstance(is_ext, str) else {}
949945
default_net_name = default_network_name_for_project(compose, net, is_ext)
950946
net_name = ext_desc.get("name", None) or net_desc.get("name", None) or default_net_name
951947
net_names.append(net_name)
@@ -981,7 +977,7 @@ def get_net_args(compose, cnt):
981977
for net_, net_config_ in multiple_nets.items():
982978
net_desc = compose.networks[net_] or {}
983979
is_ext = net_desc.get("external", None)
984-
ext_desc = is_ext if is_dict(is_ext) else {}
980+
ext_desc = is_ext if isinstance(is_ext, str) else {}
985981
default_net_name = default_network_name_for_project(compose, net_, is_ext)
986982
net_name = ext_desc.get("name", None) or net_desc.get("name", None) or default_net_name
987983

@@ -1075,10 +1071,10 @@ async def container_to_args(compose, cnt, detached=True):
10751071
for item in norm_as_list(cnt.get("dns_search", None)):
10761072
podman_args.extend(["--dns-search", item])
10771073
env_file = cnt.get("env_file", [])
1078-
if is_str(env_file) or is_dict(env_file):
1074+
if isinstance(env_file, (dict, str)):
10791075
env_file = [env_file]
10801076
for i in env_file:
1081-
if is_str(i):
1077+
if isinstance(i, str):
10821078
i = {"path": i}
10831079
path = i["path"]
10841080
required = i.get("required", True)
@@ -1096,7 +1092,7 @@ async def container_to_args(compose, cnt, detached=True):
10961092
for e in env:
10971093
podman_args.extend(["-e", e])
10981094
tmpfs_ls = cnt.get("tmpfs", [])
1099-
if is_str(tmpfs_ls):
1095+
if isinstance(tmpfs_ls, str):
11001096
tmpfs_ls = [tmpfs_ls]
11011097
for i in tmpfs_ls:
11021098
podman_args.extend(["--tmpfs", i])
@@ -1178,7 +1174,7 @@ async def container_to_args(compose, cnt, detached=True):
11781174
podman_args.extend(["--init-path", cnt["init-path"]])
11791175
entrypoint = cnt.get("entrypoint", None)
11801176
if entrypoint is not None:
1181-
if is_str(entrypoint):
1177+
if isinstance(entrypoint, str):
11821178
entrypoint = shlex.split(entrypoint)
11831179
podman_args.extend(["--entrypoint", json.dumps(entrypoint)])
11841180
platform = cnt.get("platform", None)
@@ -1189,15 +1185,15 @@ async def container_to_args(compose, cnt, detached=True):
11891185

11901186
# WIP: healthchecks are still work in progress
11911187
healthcheck = cnt.get("healthcheck", None) or {}
1192-
if not is_dict(healthcheck):
1188+
if not isinstance(healthcheck, dict):
11931189
raise ValueError("'healthcheck' must be a key-value mapping")
11941190
healthcheck_disable = healthcheck.get("disable", False)
11951191
healthcheck_test = healthcheck.get("test", None)
11961192
if healthcheck_disable:
11971193
healthcheck_test = ["NONE"]
11981194
if healthcheck_test:
11991195
# If it's a string, it's equivalent to specifying CMD-SHELL
1200-
if is_str(healthcheck_test):
1196+
if isinstance(healthcheck_test, str):
12011197
# podman does not add shell to handle command with whitespace
12021198
podman_args.extend([
12031199
"--healthcheck-command",
@@ -1259,7 +1255,7 @@ async def container_to_args(compose, cnt, detached=True):
12591255
podman_args.append(cnt["image"]) # command, ..etc.
12601256
command = cnt.get("command", None)
12611257
if command is not None:
1262-
if is_str(command):
1258+
if isinstance(command, str):
12631259
podman_args.extend(shlex.split(command))
12641260
else:
12651261
podman_args.extend([str(i) for i in command])
@@ -1302,9 +1298,9 @@ def flat_deps(services, with_extends=False):
13021298
deps.add(ext)
13031299
continue
13041300
deps_ls = srv.get("depends_on", None) or []
1305-
if is_str(deps_ls):
1301+
if isinstance(deps_ls, str):
13061302
deps_ls = [deps_ls]
1307-
elif is_dict(deps_ls):
1303+
elif isinstance(deps_ls, dict):
13081304
deps_ls = list(deps_ls.keys())
13091305
deps.update(deps_ls)
13101306
# parse link to get service name and remove alias
@@ -1467,7 +1463,7 @@ async def volume_ls(self):
14671463
def normalize_service(service, sub_dir=""):
14681464
if "build" in service:
14691465
build = service["build"]
1470-
if is_str(build):
1466+
if isinstance(build, str):
14711467
service["build"] = {"context": build}
14721468
if sub_dir and "build" in service:
14731469
build = service["build"]
@@ -1482,19 +1478,19 @@ def normalize_service(service, sub_dir=""):
14821478
context = "."
14831479
service["build"]["context"] = context
14841480
if "build" in service and "additional_contexts" in service["build"]:
1485-
if is_dict(build["additional_contexts"]):
1481+
if isinstance(build["additional_contexts"], dict):
14861482
new_additional_contexts = []
14871483
for k, v in build["additional_contexts"].items():
14881484
new_additional_contexts.append(f"{k}={v}")
14891485
build["additional_contexts"] = new_additional_contexts
14901486
for key in ("command", "entrypoint"):
14911487
if key in service:
1492-
if is_str(service[key]):
1488+
if isinstance(service[key], str):
14931489
service[key] = shlex.split(service[key])
14941490
for key in ("env_file", "security_opt", "volumes"):
14951491
if key not in service:
14961492
continue
1497-
if is_str(service[key]):
1493+
if isinstance(service[key], str):
14981494
service[key] = [service[key]]
14991495
if "security_opt" in service:
15001496
sec_ls = service["security_opt"]
@@ -1507,12 +1503,12 @@ def normalize_service(service, sub_dir=""):
15071503
service[key] = norm_as_dict(service[key])
15081504
if "extends" in service:
15091505
extends = service["extends"]
1510-
if is_str(extends):
1506+
if isinstance(extends, str):
15111507
extends = {"service": extends}
15121508
service["extends"] = extends
15131509
if "depends_on" in service:
15141510
deps = service["depends_on"]
1515-
if is_str(deps):
1511+
if isinstance(deps, str):
15161512
deps = [deps]
15171513
if is_list(deps):
15181514
deps_dict = {}
@@ -1535,9 +1531,9 @@ def normalize(compose):
15351531
def normalize_service_final(service: dict, project_dir: str) -> dict:
15361532
if "build" in service:
15371533
build = service["build"]
1538-
context = build if is_str(build) else build.get("context", ".")
1534+
context = build if isinstance(build, str) else build.get("context", ".")
15391535
context = os.path.normpath(os.path.join(project_dir, context))
1540-
if not is_dict(service["build"]):
1536+
if not isinstance(service["build"], dict):
15411537
service["build"] = {}
15421538
service["build"]["context"] = context
15431539
return service
@@ -1551,7 +1547,7 @@ def normalize_final(compose: dict, project_dir: str) -> dict:
15511547

15521548

15531549
def clone(value):
1554-
return value.copy() if is_list(value) or is_dict(value) else value
1550+
return value.copy() if is_list(value) or isinstance(value, dict) else value
15551551

15561552

15571553
def rec_merge_one(target, source):
@@ -1589,7 +1585,7 @@ def rec_merge_one(target, source):
15891585
value.extend(value2)
15901586
else:
15911587
value.extend(value2)
1592-
elif is_dict(value2):
1588+
elif isinstance(value2, dict):
15931589
rec_merge_one(value, value2)
15941590
else:
15951591
target[key] = value2
@@ -1609,7 +1605,7 @@ def resolve_extends(services, service_names, environ):
16091605
for name in service_names:
16101606
service = services[name]
16111607
ext = service.get("extends", {})
1612-
if is_str(ext):
1608+
if isinstance(ext, str):
16131609
ext = {"service": ext}
16141610
from_service_name = ext.get("service", None)
16151611
if not from_service_name:
@@ -1694,7 +1690,7 @@ def __init__(self):
16941690
]
16951691

16961692
def assert_services(self, services):
1697-
if is_str(services):
1693+
if isinstance(services, str):
16981694
services = [services]
16991695
given = set(services or [])
17001696
missing = given - self.all_services
@@ -1918,7 +1914,9 @@ def _parse_compose_file(self):
19181914
allnets = set()
19191915
for name, srv in services.items():
19201916
srv_nets = srv.get("networks", None) or self.default_net
1921-
srv_nets = list(srv_nets.keys()) if is_dict(srv_nets) else norm_as_list(srv_nets)
1917+
srv_nets = (
1918+
list(srv_nets.keys()) if isinstance(srv_nets, dict) else norm_as_list(srv_nets)
1919+
)
19221920
allnets.update(srv_nets)
19231921
given_nets = set(nets.keys())
19241922
missing_nets = allnets - given_nets
@@ -2592,7 +2590,7 @@ def get_volume_names(compose, cnt):
25922590
srv_name = cnt["_service"]
25932591
ls = []
25942592
for volume in cnt.get("volumes", []):
2595-
if is_str(volume):
2593+
if isinstance(volume, str):
25962594
volume = parse_short_mount(volume, basedir)
25972595
volume = fix_mount_dict(compose, volume, srv_name)
25982596
mount_type = volume["type"]

0 commit comments

Comments
 (0)