@@ -140,6 +140,14 @@ def __repr__(self):
140140 value += f"/{ self .variant } "
141141 return value
142142
143+ def __eq__ (self , __value : object ) -> bool :
144+ if not isinstance (__value , Platform ):
145+ return False
146+ if self .os != __value .os or self .architecture != __value .architecture :
147+ return False
148+ default_variant : str = self .default_variant (self .architecture )
149+ return (self .variant or default_variant ) == (__value .variant or default_variant )
150+
143151 @classmethod
144152 def parse (cls , platform_str : str ) -> Platform :
145153 if platform_str == "auto" :
@@ -161,6 +169,8 @@ def parse(cls, platform_str: str) -> Platform:
161169 architecture = "amd64"
162170 if architecture == "arm32" :
163171 architecture = "arm"
172+ if architecture == "i386" :
173+ architecture = "386"
164174
165175 if os not in ("linux" , "windows" ):
166176 raise ValueError (f"Invalid OS “{ os } ” from `{ platform_str } `" )
@@ -180,11 +190,6 @@ def parse(cls, platform_str: str) -> Platform:
180190 ):
181191 raise ValueError (f"Invalid arch “{ architecture } ” from `{ platform_str } `" )
182192
183- if architecture == "arm" and not variant :
184- raise ValueError (
185- f"Missing variant for arch “{ architecture } ” from `{ platform_str } `"
186- )
187-
188193 return cls (architecture = architecture , os = os , variant = variant )
189194
190195 @classmethod
@@ -204,7 +209,7 @@ def auto(cls):
204209 return cls .parse ("linux/arm64/v8" )
205210 elif machine .startswith ("arm" ):
206211 return cls .parse ("linux/arm/v6" )
207- elif machine . startswith ( "i686" ) or machine . startswith ( "i386" ):
212+ elif re . match ( r"^i(3|5|6)86" , machine ):
208213 return cls .parse ("linux/i386" )
209214 return cls .parse ("linux/amd64" )
210215
@@ -216,18 +221,6 @@ def from_payload(cls, payload: dict[str, str]):
216221 variant = payload .get ("variant" , "" ),
217222 )
218223
219- def match (self , payload : dict [str , str ]) -> bool :
220- if self .variant and self .variant != (
221- # allows matching linux/arm64 images with linux/arm/v8 requests
222- payload .get ("variant" )
223- or self .default_variant (payload .get ("architecture" , "" ))
224- ):
225- return False
226-
227- return self .os == payload .get ("os" ) and self .architecture == payload .get (
228- "architecture"
229- )
230-
231224
232225@dataclass
233226class Image :
@@ -431,7 +424,7 @@ def get_layers_from_v1_manifest(
431424 architecture = manifest .get ("architecture" , "amd64" )
432425 os = manifest .get ("os" , "linux" )
433426
434- if not platform . match ({ " architecture" : architecture , "os" : os } ):
427+ if platform != Platform ( architecture = architecture , os = os , variant = "" ):
435428 raise ValueError (
436429 f"Requested platform ({ platform } ) is not available "
437430 f"for single-platform image { image } "
@@ -476,15 +469,16 @@ def get_layers_manifest(image: Image, platform: Platform, auth: RegistryAuth):
476469 manifest = fat_manifests
477470 else :
478471 # multi-platform image
472+ platforms : list [Platform ] = []
479473 for arch_manifest in fat_manifests .get ("manifests" , []):
480- if platform .match (arch_manifest .get ("platform" , {})):
474+ if not arch_manifest .get ("platform" ):
475+ continue
476+ manifest_platform = Platform .from_payload (arch_manifest ["platform" ])
477+ if platform == manifest_platform :
481478 manifest = get_layers_manifest_for (image , auth , arch_manifest ["digest" ])
479+ platforms .append (manifest_platform )
482480
483481 if not manifest :
484- platforms = [
485- Platform .from_payload (man .get ("platform" ))
486- for man in fat_manifests .get ("manifests" , [])
487- ]
488482 raise V2ImageNotFoundError (image , platform , platforms )
489483
490484 logger .debug (f"layers_manifest={ format_json (manifest )} " )
@@ -778,16 +772,15 @@ def get_image_digest(image: Image, platform: Platform) -> str:
778772 if platform != platform .default ():
779773 raise V1ImageNotFoundError (image = image , platform = platform )
780774 return fat_manifests ["config" ]["digest" ]
781- else :
782- # multi-platform image
783- platforms : list [Platform ] = []
784- for arch_manifest in fat_manifests .get ("manifests" , []):
785- if not arch_manifest .get ("platform" ):
786- continue
787- manifest_platform = Platform .from_payload (arch_manifest ["platform" ])
788- if platform == manifest_platform :
789- return arch_manifest ["digest" ]
790- platforms .append (manifest_platform )
775+ # multi-platform image
776+ platforms : list [Platform ] = []
777+ for arch_manifest in fat_manifests .get ("manifests" , []):
778+ if not arch_manifest .get ("platform" ):
779+ continue
780+ manifest_platform = Platform .from_payload (arch_manifest ["platform" ])
781+ if platform == manifest_platform :
782+ return arch_manifest ["digest" ]
783+ platforms .append (manifest_platform )
791784
792785 raise V2ImageNotFoundError (image = image , platform = platform , platforms = platforms )
793786
0 commit comments