8888# One of the choices for user to use for requirements cache during staging
8989SKIP_REQUIREMENTS_CACHE = 'skip'
9090
91+ # Ordered list of manylinux tags from newest (strictest) to oldest (most compatible)
92+ # used for cross-platform binary dependency downloads.
93+ _MANYLINUX_PLATFORMS = [
94+ 'manylinux_2_28_x86_64' ,
95+ 'manylinux2014_x86_64' , # equivalent to manylinux_2_17
96+ 'manylinux2010_x86_64' , # equivalent to manylinux_2_12
97+ ]
98+
9199_LOGGER = logging .getLogger (__name__ )
92100
93101
@@ -762,15 +770,13 @@ def _populate_requirements_cache(
762770 # Download to a temporary directory first, then copy to cache.
763771 # This allows us to track exactly which packages are needed for this
764772 # requirements file.
765- download_dir = tempfile . mkdtemp ( dir = temp_directory )
773+ download_dir = None
766774
767775 cmd_args = [
768776 Stager ._get_python_executable (),
769777 '-m' ,
770778 'pip' ,
771779 'download' ,
772- '--dest' ,
773- download_dir ,
774780 '--find-links' ,
775781 cache_dir ,
776782 '-r' ,
@@ -781,23 +787,54 @@ def _populate_requirements_cache(
781787 ]
782788
783789 if populate_cache_with_sdists :
784- cmd_args .extend (['--no-binary' , ':all:' ])
790+ download_dir = tempfile .mkdtemp (dir = temp_directory )
791+ cmd_args .extend (['--dest' , download_dir , '--no-binary' , ':all:' ])
792+ _LOGGER .info ('Executing command: %s' , cmd_args )
793+ processes .check_output (cmd_args , stderr = processes .STDOUT )
785794 else :
786795 language_implementation_tag = 'cp'
787796 abi_suffix = 'm' if sys .version_info < (3 , 8 ) else ''
788797 abi_tag = 'cp%d%d%s' % (
789798 sys .version_info [0 ], sys .version_info [1 ], abi_suffix )
790- platform_tag = Stager ._get_platform_for_default_sdk_container ()
791- cmd_args .extend ([
792- '--implementation' ,
793- language_implementation_tag ,
794- '--abi' ,
795- abi_tag ,
796- '--platform' ,
797- platform_tag
798- ])
799- _LOGGER .info ('Executing command: %s' , cmd_args )
800- processes .check_output (cmd_args , stderr = processes .STDOUT )
799+ preferred_platform = Stager ._get_platform_for_default_sdk_container ()
800+
801+ # Fallback platform tags in case the preferred modern tag is too strict
802+ # for some dependencies on PyPI.
803+ try :
804+ start_idx = _MANYLINUX_PLATFORMS .index (preferred_platform )
805+ platforms = _MANYLINUX_PLATFORMS [start_idx :]
806+ except ValueError :
807+ platforms = [preferred_platform ]
808+
809+ last_exception = None
810+ for platform in platforms :
811+ attempt_download_dir = tempfile .mkdtemp (dir = temp_directory )
812+ attempt_cmd_args = cmd_args + [
813+ '--dest' ,
814+ attempt_download_dir ,
815+ '--implementation' ,
816+ language_implementation_tag ,
817+ '--abi' ,
818+ abi_tag ,
819+ '--platform' ,
820+ platform
821+ ]
822+ _LOGGER .info ('Executing command: %s' , attempt_cmd_args )
823+ try :
824+ processes .check_output (attempt_cmd_args , stderr = processes .STDOUT )
825+ download_dir = attempt_download_dir
826+ last_exception = None
827+ break
828+ except Exception as e :
829+ _LOGGER .warning (
830+ 'Pip download failed with platform %s, trying fallback: %s' ,
831+ platform ,
832+ e )
833+ shutil .rmtree (attempt_download_dir )
834+ last_exception = e
835+
836+ if last_exception :
837+ raise last_exception
801838
802839 # Get list of downloaded packages and copy them to the cache
803840 downloaded_packages = set ()
0 commit comments