pip-pop源码阅读

在尝试阅读pip-pop的源码过程中,遇到了理解难题,对其具体功能感到困惑。建议初学者从熟悉的库开始进行源码阅读。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

感觉还是很多地方没有读懂,这个库是做什么的都不大清楚。阅读的话还是从自己经常使用的库开始比较好。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Usage:
  pip-diff (--fresh | --stale) <reqfile1> <reqfile2> [--exclude <package>...]
  pip-diff (-h | --help)

Options:
  -h --help     Show this screen.
  --fresh       List newly added packages.
  --stale       List removed packages.
"""
import os
# 这个库需要单独去看看用法,主要用于命令行解析
from docopt import docopt
from pip.req import parse_requirements
from pip.index import PackageFinder
from pip._vendor.requests import session

requests = session()


class Requirements(object):
    def __init__(self, reqfile=None):
        # 调用父类object的__init()__方法
        super(Requirements, self).__init__()
        # 接收传入的r1
        self.path = reqfile
        self.requirements = []

        # 如果reqfile不为空则调用.load()
        if reqfile:
            self.load(reqfile)

    # print Requirements对象的时候回直接输出这个字符串
    def __repr__(self):
        return '<Requirements \'{}\'>'.format(self.path)

    # 哇,好难还需要看pip库的内容。大概是建立reqfile中所需要关联的库吧,然后存在self.requirements列表里
    # PackageFinder这个类实现的功能,需要看pip库的源码
    def load(self, reqfile):
        if not os.path.exists(reqfile):
            raise ValueError('The given requirements file does not exist.')

        finder = PackageFinder([], [], session=requests)
        for requirement in parse_requirements(reqfile, finder=finder, session=requests):
            if requirement.req:
                if not getattr(requirement.req, 'name', None):
                    # Prior to pip 8.1.2 the attribute `name` did not exist.
                    requirement.req.name = requirement.req.project_name
                self.requirements.append(requirement.req)


    def diff(self, requirements, ignore_versions=False, excludes=None):
        r1 = self
        # 外面传入的<reqfile2> requirements对象
        r2 = requirements
        results = {'fresh': [], 'stale': []}

        # 如果忽略版本号的话,就存入管理库的名字,如果不忽略的话就直接存入
        # Generate fresh packages.
        other_reqs = (
            [r.name for r in r1.requirements]
            if ignore_versions else r1.requirements
        )

        # 遍历<reqfile2>对象的 self.requirements,将参数存入r列表中
        for req in r2.requirements:
            # 如果忽略版本号的话,就存入管理库的名字,如果不忽略的话就直接存入
            r = req.name if ignore_versions else req

            # 如果r中的参数不在other_reqs和excludes中的话存入到 results['fresh']
            if r not in other_reqs and r not in excludes:
                results['fresh'].append(req)

        # 与之前fresh流程一样...
        # 如果忽略版本号的话,就存入管理库的名字,如果不忽略的话就直接存入
        # Generate stale packages.
        other_reqs = (
            [r.name for r in r2.requirements]
            if ignore_versions else r2.requirements
        )

        # 如果r中的参数不在other_reqs和excludes中的话存入到 results['stale']
        for req in r1.requirements:
            r = req.name if ignore_versions else req

            if r not in other_reqs and r not in excludes:
                results['stale'].append(req)

        return results


def diff(r1, r2, include_fresh=False, include_stale=False, excludes=None):
    # 如果使用了指令stale则为True否则为False
    include_versions = True if include_stale else False
    # 如果有package则为这个参数,不然为空
    excludes = excludes if len(excludes) else []

    try:
        # 创建Requirements对象r1,r2 /接着查看这个类具体实现
        r1 = Requirements(r1)
        r2 = Requirements(r2)
    except ValueError:
        print('There was a problem loading the given requirements files.')
        exit(os.EX_NOINPUT)

    # 将Requirements.diff()执行结果存入结果中
    results = r1.diff(r2, ignore_versions=True, excludes=excludes)

    # 如果是fresh指令则输出这个
    if include_fresh:
        for line in results['fresh']:
            print(line.name if include_versions else line)

    # 如果是stale指令则输出这个
    if include_stale:
        for line in results['stale']:
            print(line.name if include_versions else line)


def main():
    # docopt 命令行参数解释器,会将文件头的注释转成字典,调用docopt(__doc__, version='pip-diff')
    # 时,可以获取到一个字典。具体用法可以参考博客:https://xuanwo.org/2016/04/04/docopt-intro/
    args = docopt(__doc__, version='pip-diff')

    kwargs = {
        'r1': args['<reqfile1>'],
        'r2': args['<reqfile2>'],
        'include_fresh': args['--fresh'],
        'include_stale': args['--stale'],
        'excludes': args['<package>']
    }

    # 执行diff函数,同时将kwargs传入
    diff(**kwargs)


if __name__ == '__main__':
    # 程序执行入口
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值