@@ -88,11 +88,28 @@ def resolve_version(
8888 return self ._resolved_requirements [req_str ]
8989
9090 pbi = self .ctx .package_build_info (req )
91- if pbi .pre_built :
92- source_url , resolved_version = self ._resolve_prebuilt_with_history (
93- req = req ,
94- req_type = req_type ,
95- )
91+
92+ # Check if package has version-specific settings (any version-specific config)
93+ variant_info = pbi ._ps .variants .get (pbi ._variant )
94+ has_version_specific_prebuilt = (
95+ variant_info and variant_info .versions and len (variant_info .versions ) > 0
96+ )
97+
98+ if pbi .pre_built or has_version_specific_prebuilt :
99+ try :
100+ source_url , resolved_version = self ._resolve_prebuilt_with_history (
101+ req = req ,
102+ req_type = req_type ,
103+ )
104+ except Exception as e :
105+ # Version-specific prebuilt resolution failed, fall back to source
106+ logger .debug (
107+ f"{ req .name } : prebuilt resolution failed, falling back to source: { e } "
108+ )
109+ source_url , resolved_version = self ._resolve_source_with_history (
110+ req = req ,
111+ req_type = req_type ,
112+ )
96113 else :
97114 source_url , resolved_version = self ._resolve_source_with_history (
98115 req = req ,
@@ -185,7 +202,8 @@ def bootstrap(self, req: Requirement, req_type: RequirementType) -> Version:
185202
186203 source_url_type = sources .get_source_type (self .ctx , req )
187204
188- if pbi .pre_built :
205+ # Use version-aware prebuilt check now that we have resolved_version
206+ if pbi .is_pre_built (resolved_version ):
189207 wheel_filename , unpack_dir = self ._download_prebuilt (
190208 req = req ,
191209 req_type = req_type ,
@@ -826,6 +844,19 @@ def _resolve_prebuilt_with_history(
826844 req : Requirement ,
827845 req_type : RequirementType ,
828846 ) -> tuple [str , Version ]:
847+ # Try version-specific resolution FIRST (highest priority)
848+ # This allows version-specific wheel_server_url settings to override
849+ # any cached resolutions from previous bootstraps or current graph
850+ try :
851+ wheel_url , resolved_version = (
852+ self ._resolve_prebuilt_with_version_specific_urls (req , req_type )
853+ )
854+ return (wheel_url , resolved_version )
855+ except Exception :
856+ # No version-specific settings matched, fall back to cached resolution
857+ pass
858+
859+ # Fall back to cached resolution from graph
829860 cached_resolution = self ._resolve_from_graph (
830861 req = req ,
831862 req_type = req_type ,
@@ -835,14 +866,70 @@ def _resolve_prebuilt_with_history(
835866 if cached_resolution and not req .url :
836867 wheel_url , resolved_version = cached_resolution
837868 logger .debug (f"resolved from previous bootstrap to { resolved_version } " )
838- else :
839- servers = wheels .get_wheel_server_urls (
840- self .ctx , req , cache_wheel_server_url = resolver .PYPI_SERVER_URL
841- )
842- wheel_url , resolved_version = wheels .resolve_prebuilt_wheel (
843- ctx = self .ctx , req = req , wheel_server_urls = servers , req_type = req_type
844- )
845- return (wheel_url , resolved_version )
869+ return (wheel_url , resolved_version )
870+
871+ # No cached resolution found, raise to trigger fallback to source resolution
872+ raise ValueError ("No prebuilt resolution found" )
873+
874+ def _resolve_prebuilt_with_version_specific_urls (
875+ self ,
876+ req : Requirement ,
877+ req_type : RequirementType ,
878+ ) -> tuple [str , Version ]:
879+ """Resolve prebuilt wheel using version-specific wheel server URLs if configured."""
880+ pbi = self .ctx .package_build_info (req )
881+
882+ # Check if there are version-specific settings
883+ variant_info = pbi ._ps .variants .get (pbi ._variant )
884+ if not variant_info or not variant_info .versions :
885+ raise ValueError ("No version-specific settings configured" )
886+
887+ # Get the constraint for this package
888+ constraint = self .ctx .constraints .get_constraint (req .name )
889+
890+ # Try to resolve using version-specific wheel server URLs
891+ for version_str , version_settings in variant_info .versions .items ():
892+ # Only process versions that have both wheel_server_url and pre_built=True
893+ if not (version_settings .wheel_server_url and version_settings .pre_built ):
894+ continue
895+
896+ # Only try this version if it satisfies the requirement specifier AND constraint
897+ try :
898+ version_obj = Version (version_str )
899+
900+ # Check requirement specifier (if present)
901+ if req .specifier and version_obj not in req .specifier :
902+ continue
903+
904+ # Check constraint (if present) - this is the version from constraints.txt
905+ if constraint and version_obj not in constraint .specifier :
906+ continue
907+
908+ except Exception :
909+ continue # Skip invalid version strings
910+
911+ # Create a constraint for this specific version
912+ version_req = Requirement (f"{ req .name } =={ version_str } " )
913+
914+ try :
915+ # Try to resolve this specific version from the version-specific server
916+ wheel_url , resolved_version = wheels .resolve_prebuilt_wheel (
917+ ctx = self .ctx ,
918+ req = version_req ,
919+ wheel_server_urls = [version_settings .wheel_server_url ],
920+ req_type = req_type ,
921+ )
922+ logger .info (
923+ f"{ req .name } : using version-specific prebuilt wheel "
924+ f"{ resolved_version } from { version_settings .wheel_server_url } "
925+ )
926+ return (wheel_url , resolved_version )
927+ except Exception :
928+ # Version not found on this server, try next
929+ continue
930+
931+ # No matching version-specific prebuilt settings found
932+ raise ValueError ("No matching version-specific prebuilt settings found" )
846933
847934 def _resolve_from_graph (
848935 self ,
@@ -949,7 +1036,8 @@ def _add_to_graph(
9491036 req = req ,
9501037 req_version = req_version ,
9511038 download_url = download_url ,
952- pre_built = pbi .pre_built ,
1039+ # Use version-aware prebuilt check for dependency graph
1040+ pre_built = pbi .is_pre_built (req_version ),
9531041 )
9541042 self .ctx .write_to_graph_to_file ()
9551043
0 commit comments