From 528d9b1ce58daeb26c6c5a46a191bcbdb49a0f20 Mon Sep 17 00:00:00 2001 From: Siarhei Siniak Date: Thu, 23 Jan 2025 12:17:07 +0300 Subject: [PATCH] [+] integrate uv pip compile --- python/online/fxreader/pr34/commands.py | 23 +- .../fxreader/pr34/commands_typed/pip.py | 277 +++++++++++------- requirements-archlinux.txt | 1 - requirements.txt | 16 - 4 files changed, 175 insertions(+), 142 deletions(-) delete mode 100644 requirements-archlinux.txt delete mode 100644 requirements.txt diff --git a/python/online/fxreader/pr34/commands.py b/python/online/fxreader/pr34/commands.py index 8590592..2f7c095 100644 --- a/python/online/fxreader/pr34/commands.py +++ b/python/online/fxreader/pr34/commands.py @@ -3891,20 +3891,15 @@ def pip_resolve(args: list[str]) -> None: options, argv = parser.parse_known_args(args) from online.fxreader.pr34.commands_typed.pip import pip_resolve - sys.stdout.write('\n'.join([ - '#%s\n%s %s' % ( - o.url, - o.constraint, - ' '.join([ - '--hash=sha256:%s' % o2 - for o2 in o.sha256 - ]) - ) - for o in pip_resolve( - argv, - mode=options.mode, - ) - ])) + + resolve_res = pip_resolve( + argv, + mode=options.mode, + ) + + assert not resolve_res.txt is None + + sys.stdout.write(resolve_res.txt) sys.stdout.flush() def commands_cli( diff --git a/python/online/fxreader/pr34/commands_typed/pip.py b/python/online/fxreader/pr34/commands_typed/pip.py index e48cf67..8816858 100644 --- a/python/online/fxreader/pr34/commands_typed/pip.py +++ b/python/online/fxreader/pr34/commands_typed/pip.py @@ -14,7 +14,9 @@ import pip._internal.operations.prepare import unittest.mock import logging -from typing import (Literal,) +from typing import ( + Literal, +) logger = logging.getLogger(__name__) @@ -28,7 +30,14 @@ def pip_show( ) ) + class pip_resolve_t: + class kwargs_t: + class mode_t(enum.StrEnum): + copy_paste = "copy_paste" + monkey_patch = "monkey_patch" + uv_pip_compile = "uv_pip_compile" + class res_t: @dataclasses.dataclass class download_info_t: @@ -36,29 +45,41 @@ class pip_resolve_t: sha256: str constraint: str + txt: Optional[str] = None + entries: Optional[list[download_info_t]] = None + + +def pip_resolve_entries_to_txt( + entries: list[pip_resolve_t.res_t.download_info_t] +) -> str: + return '\n'.join([ + '#%s\n%s %s' % ( + o.url, + o.constraint, + ' '.join([ + '--hash=sha256:%s' % o2 + for o2 in o.sha256 + ]) + ) + for o in entries + ]) + def pip_resolve( argv: list[str], - mode: Literal['copy_paste', 'monkey_patch'], -) -> list[ - pip_resolve_t.res_t.download_info_t -]: - if mode == 'copy_paste': + mode: pip_resolve_t.kwargs_t.mode_t, +) -> list[pip_resolve_t.res_t.download_info_t]: + if mode is pip_resolve_t.kwargs_t.mode_t.copy_paste: with contextlib.ExitStack() as stack: - stack.enter_context( - pip._internal.utils.temp_dir.global_tempdir_manager() - ) - + stack.enter_context(pip._internal.utils.temp_dir.global_tempdir_manager()) + t2 = pip._internal.cli.main_parser.create_main_parser() - t3 = t2.parse_args(['download']) - t1 = pip._internal.commands.download.DownloadCommand( - 'blah', - 'shit' - ) + t3 = t2.parse_args(["download"]) + t1 = pip._internal.commands.download.DownloadCommand("blah", "shit") stack.enter_context(t1.main_context()) - #options = pip._internal.commands.download.Values() + # options = pip._internal.commands.download.Values() options = t3[0] options.python_version = None options.platforms = [] @@ -83,7 +104,7 @@ def pip_resolve( options.progress_bar = True options.require_hashes = None options.ignore_requires_python = None - #options.cache_dir + # options.cache_dir pip._internal.commands.download.cmdoptions.check_dist_restriction(options) # t1._in_main_context = True session = t1.get_default_session(options) @@ -94,16 +115,21 @@ def pip_resolve( target_python=target_python, ignore_requires_python=options.ignore_requires_python, ) - build_tracker = t1.enter_context(pip._internal.commands.download.get_build_tracker()) - reqs = t1.get_requirements([ - #'pip', 'uv', 'ipython', - *argv, - ], options, finder, session) + build_tracker = t1.enter_context( + pip._internal.commands.download.get_build_tracker() + ) + reqs = t1.get_requirements( + [ + #'pip', 'uv', 'ipython', + *argv, + ], + options, + finder, + session, + ) pip._internal.commands.download.check_legacy_setup_py_options(options, reqs) directory = pip._internal.commands.download.TempDirectory( - delete=True, - kind='download', - globally_managed=True + delete=True, kind="download", globally_managed=True ) preparer = t1.make_requirement_preparer( temp_build_dir=directory, @@ -126,50 +152,59 @@ def pip_resolve( t1.trace_basic_info(finder) requirement_set = resolver.resolve(reqs, check_supported_wheels=True) - return [ - pip_resolve_t.res_t.download_info_t( - constraint=k, - sha256=v.download_info.info.hashes['sha256'], - url=v.download_info.url, - ) - for k, v in requirement_set.requirements.items() - ] - elif mode == 'monkey_patch': + res = pip_resolve_t.res_t( + entries=[ + pip_resolve_t.res_t.download_info_t( + constraint=k, + sha256=v.download_info.info.hashes["sha256"], + url=v.download_info.url, + ) + for k, v in requirement_set.requirements.items() + ], + ) + res.txt = pip_resolve_entries_to_txt( + res.entries + ) + + return res + elif mode is pip_resolve_t.kwargs_t.mode_t.monkey_patch: downloader_call_def = pip._internal.network.download.Downloader.__call__ def downloader_call(*args): - logger.info(dict( - url=args[1].url, - )) + logger.info( + dict( + url=args[1].url, + ) + ) return downloader_call_def(*args) - batch_downloader_call_def = pip._internal.network.download.BatchDownloader.__call__ + batch_downloader_call_def = ( + pip._internal.network.download.BatchDownloader.__call__ + ) def batch_downloader_call(*args): # print(args) - logger.info(dict( - args=args, - )) + logger.info( + dict( + args=args, + ) + ) - return [ - (o, ('/dev/null', None)) - for o in args[1] - ] + return [(o, ("/dev/null", None)) for o in args[1]] - #base_resolver_resolve_def = pip._internal.resolution.base.BaseResolver.resolve - base_resolver_resolve_def = pip._internal.resolution.resolvelib.resolver.Resolver.resolve + # base_resolver_resolve_def = pip._internal.resolution.base.BaseResolver.resolve + base_resolver_resolve_def = ( + pip._internal.resolution.resolvelib.resolver.Resolver.resolve + ) result_requirements = [] def base_resolver_resolve(*args, **kwargs): # print(args, kwargs) - res = base_resolver_resolve_def( - *args, - **kwargs - ) + res = base_resolver_resolve_def(*args, **kwargs) result_requirements.append(res) raise NotImplementedError @@ -178,108 +213,96 @@ def pip_resolve( get_http_url_def = pip._internal.operations.prepare.get_http_url def get_http_url(link, download, download_dir=None, hashes=None): + logger.info( + dict( + url=link.url, + hashes=hashes, + ) + ) - logger.info(dict( - url=link.url, - hashes=hashes, - )) - - if link.url.endswith('.whl'): - print('blah') + if link.url.endswith(".whl"): + print("blah") hashes = None - return '/dev/null', None + return "/dev/null", None else: - return get_http_url_def( - link, - download, - download_dir, - hashes - ) + return get_http_url_def(link, download, download_dir, hashes) - prepare_linked_requirements_more_def = \ - pip._internal.operations.prepare.RequirementPreparer\ - .prepare_linked_requirements_more + prepare_linked_requirements_more_def = pip._internal.operations.prepare.RequirementPreparer.prepare_linked_requirements_more - def prepare_linked_requirements_more( - _self, reqs, *args, **kwargs - ): + def prepare_linked_requirements_more(_self, reqs, *args, **kwargs): result_requirements.append(reqs) raise NotImplementedError - _complete_partial_requirements_def = \ - pip._internal.operations.prepare.RequirementPreparer\ - ._complete_partial_requirements + _complete_partial_requirements_def = pip._internal.operations.prepare.RequirementPreparer._complete_partial_requirements - def _complete_partial_requirements( - _self, reqs, *args, **kwargs - ): + def _complete_partial_requirements(_self, reqs, *args, **kwargs): result_requirements.append(reqs) raise NotImplementedError patches = [] patches.append( unittest.mock.patch.object( - pip._internal.network.download.Downloader, - '__call__', - downloader_call + pip._internal.network.download.Downloader, "__call__", downloader_call ) ) - #patches.append( + # patches.append( # unittest.mock.patch.object( # pip._internal.network.download.BatchDownloader, # '__call__', # batch_downloader_call # ) - #) - #patches.append( + # ) + # patches.append( # unittest.mock.patch.object( # pip._internal.resolution.base.BaseResolver, 'resolve', base_resolver_resolve)) patches.append( unittest.mock.patch.object( pip._internal.resolution.resolvelib.resolver.Resolver, - 'resolve', - base_resolver_resolve + "resolve", + base_resolver_resolve, ) ) patches.append( unittest.mock.patch.object( pip._internal.operations.prepare, - 'get_http_url', + "get_http_url", get_http_url, ) ) patches.append( unittest.mock.patch.object( pip._internal.operations.prepare.RequirementPreparer, - 'prepare_linked_requirements_more', - prepare_linked_requirements_more + "prepare_linked_requirements_more", + prepare_linked_requirements_more, ) ) - #patches.append( + # patches.append( # unittest.mock.patch.object( # pip._internal.operations.prepare.RequirementPreparer, # '_complete_partial_requirements', # _complete_partial_requirements # ) - #) + # ) with contextlib.ExitStack() as stack: for p in patches: stack.enter_context(p) - - pip._internal.cli.main.main([ - 'download', - '-q', - '--no-cache', - '-d', - '/dev/null', - *argv, - # 'numpy', - ]) - - #return sum([ + + pip._internal.cli.main.main( + [ + "download", + "-q", + "--no-cache", + "-d", + "/dev/null", + *argv, + # 'numpy', + ] + ) + + # return sum([ # [ # pip_resolve_t.res_t.download_info_t( # constraint=k, @@ -289,15 +312,47 @@ def pip_resolve( # for k, v in o.requirements.items() # ] # for o in result_requirements - #], []) + # ], []) logger.warn(result_requirements) - return [ - pip_resolve_t.res_t.download_info_t( - constraint=str(o.req), - sha256=o.hashes()._allowed['sha256'], - url=o.link.url, - ) - for o in sum(result_requirements, []) - ] + + res = pip_resolve_t.res_t( + entries=[ + pip_resolve_t.res_t.download_info_t( + constraint=str(o.req), + sha256=o.hashes()._allowed["sha256"], + url=o.link.url, + ) + for o in sum(result_requirements, []) + ], + ) + res.txt = pip_resolve_entries_to_txt( + res.entries + ) + + return res + elif mode is pip_resolve_t.kwargs_t.mode_t.uv_pip_compile: + pip_freeze = subprocess.check_output( + [ + sys.executable, + "-m", + "uv", + "pip", + "freeze", + ], + ).decode('utf-8') + pip_compile = subprocess.check_output( + [ + sys.executable, '-m', + 'uv', 'pip', 'compile', + '--generate-hashes', + '-', + + ], + input=pip_freeze.encode('utf-8') + ).decode('utf-8') + + return pip_resolve_t.res_t( + txt=pip_compile, + ) else: raise NotImplementedError diff --git a/requirements-archlinux.txt b/requirements-archlinux.txt deleted file mode 100644 index 162b1f7..0000000 --- a/requirements-archlinux.txt +++ /dev/null @@ -1 +0,0 @@ -python-build diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 9fa0f40..0000000 --- a/requirements.txt +++ /dev/null @@ -1,16 +0,0 @@ -ipython -jupyter -notebook -requests -pyquery -youtube-dl -gdown -aiohttp -mypy -ruff -cython -numpy -scoping -types-setuptools -uvloop -pydantic \ No newline at end of file