1+ from __future__ import annotations
2+
13import copy
24import string
35import sys
79from enum import Enum
810from os import urandom
911from random import randint
10- from typing import Any , Dict , List , Optional , Union
12+ from typing import TYPE_CHECKING , Any , Dict , List , Optional , Union
13+
14+ if TYPE_CHECKING :
15+ from linode_api4 .objects .volume import Volume
1116from urllib import parse
1217
1318from linode_api4 .common import load_and_validate_keys
4045from linode_api4 .objects .serializable import JSONObject , StrEnum
4146from linode_api4 .objects .vpc import VPC , VPCSubnet
4247from linode_api4 .paginated_list import PaginatedList
43- from linode_api4 .util import drop_null_keys , generate_device_suffixes
48+ from linode_api4 .util import (
49+ drop_null_keys ,
50+ generate_device_suffixes ,
51+ normalize_as_list ,
52+ )
4453
4554PASSWORD_CHARS = string .ascii_letters + string .digits + string .punctuation
4655MIN_DEVICE_LIMIT = 8
@@ -1249,14 +1258,14 @@ def config_create(
12491258 kernel : Kernel | str | None = None ,
12501259 label : str | None = None ,
12511260 devices : (
1252- Union ["Disk" , "Volume" , dict [str , Any ]]
1253- | list [Union ["Disk" , "Volume" , dict [str , Any ]]]
1261+ Disk
1262+ | Volume
1263+ | dict [str , Any ]
1264+ | list [Disk | Volume | dict [str , Any ]]
12541265 | None
12551266 ) = None ,
1256- disks : Union ["Disk" , int ] | list [Union ["Disk" , int ]] | None = None ,
1257- volumes : (
1258- Union ["Volume" , int ] | list [Union ["Volume" , int ]] | None
1259- ) = None ,
1267+ disks : Disk | int | list [Disk | int ] | None = None ,
1268+ volumes : Volume | int | list [Volume | int ] | None = None ,
12601269 interfaces : list [ConfigInterface | dict [str , Any ]] | None = None ,
12611270 ** kwargs ,
12621271 ) -> Config :
@@ -1269,12 +1278,13 @@ def config_create(
12691278 :param label: The config label
12701279 :param disks: The list of disks, starting at sda, to map to this config.
12711280 :param volumes: The volumes, starting after the last disk, to map to this
1272- config
1281+ config.
12731282 :param devices: A list of devices to assign to this config, in device
1274- index order, a raw device mapping dict to pass directly to the API
1275- (e.g. ``{"sda": {"disk_id": 123}, "sdb": Volume(...)}``), or
1276- a single Disk or Volume.
1277- If this is given, you may not include disks or volumes.
1283+ index order, a raw device mapping dict to pass directly to the API
1284+ (e.g. ``{"sda": {"disk_id": 123}, "sdb": Volume(...)}``), or
1285+ a single Disk or Volume.
1286+ If this is given, you may not include disks or volumes.
1287+ :param interfaces: A list of ConfigInterface objects or dicts to assign to this config.
12781288 :param **kwargs: Any other arguments accepted by the api.
12791289
12801290 :returns: A new Linode Config
@@ -1298,7 +1308,7 @@ def config_create(
12981308 for suffix in generate_device_suffixes (device_limit )
12991309 ]
13001310
1301- def _flatten_device (device : Optional [ Union [ Disk , Volume ]] ):
1311+ def _flatten_device (device : Disk | Volume | None ):
13021312 if device is None :
13031313 return None
13041314 elif isinstance (device , Disk ):
@@ -1308,15 +1318,21 @@ def _flatten_device(device: Optional[Union[Disk, Volume]]):
13081318
13091319 raise TypeError ("Disk or Volume expected!" )
13101320
1311- def _device_entry (device : Union [Disk , Volume , int ], key : str ):
1312- return (
1313- {key : device if isinstance (device , int ) else device .id }
1314- if isinstance (device , int )
1315- else _flatten_device (device )
1316- )
1321+ def _device_entry (device : Disk | Volume | int , key : str ):
1322+ if isinstance (device , (Disk , Volume )):
1323+ return _flatten_device (device )
1324+
1325+ try :
1326+ device_id = int (device )
1327+ except (TypeError , ValueError ):
1328+ raise TypeError (
1329+ "Disk, Volume, or integer ID expected!"
1330+ ) from None
1331+
1332+ return {key : device_id }
13171333
13181334 def _build_devices ():
1319- # Devices is a dict, pass through
1335+ # Devices is a dict, flatten and pass through
13201336 if isinstance (devices , dict ):
13211337 return {
13221338 k : (
@@ -1329,33 +1345,22 @@ def _build_devices():
13291345
13301346 device_list = []
13311347
1332- # "Devices" was provided
13331348 if devices :
1334- devices_norm = (
1335- devices if isinstance (devices , (list , tuple )) else [devices ]
1336- )
1337-
13381349 device_list += [
1339- _flatten_device (device ) for device in devices_norm
1350+ _flatten_device (device )
1351+ for device in normalize_as_list (disks )
13401352 ]
13411353
13421354 if disks :
1343- disks_norm = (
1344- disks if isinstance (disks , (list , tuple )) else [disks ]
1345- )
1346-
13471355 device_list += [
1348- _device_entry (disk , "disk_id" ) for disk in disks_norm
1356+ _device_entry (disk , "disk_id" )
1357+ for disk in normalize_as_list (disks )
13491358 ]
13501359
13511360 if volumes :
1352- volumes_norm = (
1353- volumes if isinstance (volumes , (list , tuple )) else [volumes ]
1354- )
1355-
13561361 device_list += [
13571362 _device_entry (volume , "volume_id" )
1358- for volume in volumes_norm
1363+ for volume in normalize_as_list ( disks )
13591364 ]
13601365
13611366 return {
0 commit comments