解决AttributeError: 'module' object has no attribute 'main' 安装第三方包报错

本文介绍如何使用PyCharm中的packaging_tool.py文件进行软件包管理,包括安装、卸载、列出已安装包等功能,并提供了代码示例。

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

1.找到pycharm 目录下的 \helper\packaging_tool.py 文件
2.用新版pycharm 的packaging_tool.py 替换 旧版 同名文件
文件代码如下:
import sys
import traceback
import getopt
import os
 
ERROR_WRONG_USAGE = 1
ERROR_NO_PIP = 2
ERROR_NO_SETUPTOOLS = 3
ERROR_EXCEPTION = 4
 
os.putenv("PIP_REQUIRE_VIRTUALENV", "false")
 
def exit(retcode):
    major, minor, micro, release, serial = sys.version_info
    version = major * 10 + minor
    if version < 25:
        import os
        os._exit(retcode)
    else:
        sys.exit(retcode)
 
 
def usage():
    sys.stderr.write('Usage: packaging_tool.py <list|install|uninstall|pyvenv>\n')
    sys.stderr.flush()
    exit(ERROR_WRONG_USAGE)
 
 
def error(message, retcode):
    sys.stderr.write('Error: %s\n' % message)
    sys.stderr.flush()
    exit(retcode)
 
 
def error_no_pip():
    type, value, tb = sys.exc_info()
    if tb is not None and tb.tb_next is None:
        error("Python packaging tool 'pip' not found", ERROR_NO_PIP)
    else:
        error(traceback.format_exc(), ERROR_EXCEPTION)
 
 
def do_list():
    try:
        import pkg_resources
    except ImportError:
        error("Python packaging tool 'setuptools' not found", ERROR_NO_SETUPTOOLS)
    for pkg in pkg_resources.working_set:
        try:
            requirements = pkg.requires()
        except Exception:
            requirements = []
        requires = ':'.join([str(x) for x in requirements])
        sys.stdout.write('\t'.join([pkg.project_name, pkg.version, pkg.location, requires])+chr(10))
    sys.stdout.flush()
 
 
def do_install(pkgs):  
    return pip_main(['install'] + pkgs)
 
 
def do_uninstall(pkgs):
    return pip_main(['uninstall', '-y'] + pkgs)
 
 
def pip_main(args):
    try:
        import pip
    except ImportError:
        error_no_pip()
 
    try:
        func = pip.main
    except AttributeError:
        from pip._internal import main as func
 
    func(args)
 
 
def do_pyvenv(path, system_site_packages):
    try:
        import venv
    except ImportError:
        error("Standard Python 'venv' module not found", ERROR_EXCEPTION)
    # In Python >= 3.4 venv.create() has a new parameter with_pip=False
    # that allows to automatically install setuptools and pip with the module
    # ensurepip. Unfortunately, we cannot use this parameter and have to
    # bootstrap these packages ourselves, since some distributions of CPython
    # on Ubuntu don't include ensurepip.
    venv.create(path, system_site_packages=system_site_packages)
 
 
def do_untar(name):
    import tempfile
 
    directory_name = tempfile.mkdtemp("pycharm-management")
 
    import tarfile
 
    tar = tarfile.open(name)
    for item in tar:
        tar.extract(item, directory_name)
 
    sys.stdout.write(directory_name+chr(10))
    sys.stdout.flush()
    return 0
 
 
def mkdtemp_ifneeded():
    try:
        ind = sys.argv.index('--build-dir')
        if not os.path.exists(sys.argv[ind + 1]):
            import tempfile
 
            sys.argv[ind + 1] = tempfile.mkdtemp('pycharm-packaging')
            return sys.argv[ind + 1]
    except:
        pass
 
    return None
 
 
def main():
    try:
        # As a workaround for #885 in setuptools, don't expose other helpers
        # in sys.path so as not no confuse it with possible combination of
        # namespace/ordinary packages
        sys.path.remove(os.path.dirname(__file__))
    except ValueError:
        pass
 
    retcode = 0
    try:
        if len(sys.argv) < 2:
            usage()
        cmd = sys.argv[1]
        if cmd == 'list':
            if len(sys.argv) != 2:
                usage()
            do_list()
        elif cmd == 'install':
            if len(sys.argv) < 2:
                usage()
 
            rmdir = mkdtemp_ifneeded()
 
            pkgs = sys.argv[2:]
            retcode = do_install(pkgs)
 
            if rmdir is not None:
                import shutil
                shutil.rmtree(rmdir)
 
 
        elif cmd == 'untar':
            if len(sys.argv) < 2:
                usage()
            name = sys.argv[2]
            retcode = do_untar(name)
        elif cmd == 'uninstall':
            if len(sys.argv) < 2:
                usage()
            pkgs = sys.argv[2:]
            retcode = do_uninstall(pkgs)
        elif cmd == 'pyvenv':
            opts, args = getopt.getopt(sys.argv[2:], '', ['system-site-packages'])
            if len(args) != 1:
                usage()
            path = args[0]
            system_site_packages = False
            for opt, arg in opts:
                if opt == '--system-site-packages':
                    system_site_packages = True
            do_pyvenv(path, system_site_packages)
        else:
            usage()
    except Exception:
        traceback.print_exc()
        exit(ERROR_EXCEPTION)
    exit(retcode)
 
if __name__ == '__main__':
    main()
 
替换掉代码即可

转载于:https://www.cnblogs.com/wujf-myblog/p/9620315.html

请选择要使用的pip源: RUN Choose Task:[请输入括号内的数字] 请选择pip源: [1]:清华源 - https://pypi.tuna.tsinghua.edu.cn/simple [2]:阿里云 - https://mirrors.aliyun.com/pypi/simple [3]:中国科技大学 - https://pypi.mirrors.ustc.edu.cn/simple [4]:华为云 - https://repo.huaweicloud.com/repository/pypi/simple [0]:quit 请输入[]内的数字以选择:3 您选择了: https://pypi.mirrors.ustc.edu.cn/simple 正在使用 https://pypi.mirrors.ustc.edu.cn/simple 安装 rosdepc... Run CMD Task:[sudo pip3 install -i https://pypi.mirrors.ustc.edu.cn/simple rosdepc --break-system-packages] [-][0.50s] CMD Result:code:2 检测到程序发生异常退出,请打开:https://fishros.org.cn/forum 携带如下内容进行反馈 标题:使用一键安装过程中遇到程序崩溃 ``` Traceback (most recent call last): File "/tmp/fishinstall/install.py", line 134, in <module> main() File "/tmp/fishinstall/install.py", line 123, in main run_tool_file(tools[code]['tool'].replace("/",".")) File "/tmp/fishinstall/tools/base.py", line 1478, in run_tool_file if tool.run()==False: return False File "/tmp/fishinstall/tools/tool_config_rosdep.py", line 94, in run self.install_rosdepc() File "/tmp/fishinstall/tools/tool_config_rosdep.py", line 85, in install_rosdepc PrintUtils.print_warning("安装失败,尝试使用其他方式安装...") AttributeError: type object 'PrintUtils' has no attribute 'print_warning' ``` 本次运行详细日志文件已保存至 /tmp/fishros_install.log 检测到本次运行出现失败命令,直接退出按Ctrl+C,按任意键上传日志并退出
08-13
import contextlib import copy import functools import pprint import textwrap import typing import blinker import blinker._saferef from seleniumwire.thirdparty.mitmproxy import exceptions from seleniumwire.thirdparty.mitmproxy.utils import typecheck """ The base implementation for Options. """ unset = object() class _Option: __slots__ = ("name", "typespec", "value", "_default", "choices", "help") def __init__( self, name: str, typespec: typing.Union[type, object], # object for Optional[x], which is not a type. default: typing.Any, help: str, choices: typing.Optional[typing.Sequence[str]] ) -> None: typecheck.check_option_type(name, default, typespec) self.name = name self.typespec = typespec self._default = default self.value = unset self.help = textwrap.dedent(help).strip().replace("\n", " ") self.choices = choices def __repr__(self): return "{value} [{type}]".format(value=self.current(), type=self.typespec) @property def default(self): return copy.deepcopy(self._default) def current(self) -> typing.Any: if self.value is unset: v = self.default else: v = self.value return copy.deepcopy(v) def set(self, value: typing.Any) -> None: typecheck.check_option_type(self.name, value, self.typespec) self.value = value def reset(self) -> None: self.value = unset def has_changed(self) -> bool: return self.current() != self.default def __eq__(self, other) -> bool: for i in self.__slots__: if getattr(self, i) != getattr(other, i): return False return True def __deepcopy__(self, _): o = _Option( self.name, self.typespec, self.default, self.help, self.choices ) if self.has_changed(): o.value = self.current() return o class OptManager: """ OptManager is the base class from which Options objects are derived. .changed is a blinker Signal that triggers whenever options are updated. If any handler in the chain raises an exceptions.OptionsError exception, all changes are rolled back, the exception is suppressed, and the .errored signal is notified. Optmanager always returns a deep copy of options to ensure that mutation doesn't change the option state inadvertently. """ def __init__(self): self.deferred: typing.Dict[str, str] = {} self.changed = blinker.Signal() self.errored = blinker.Signal() # Options must be the last attribute here - after that, we raise an # error for attribute assigment to unknown options. self._options: typing.Dict[str, typing.Any] = {} def add_option( self, name: str, typespec: typing.Union[type, object], default: typing.Any, help: str, choices: typing.Optional[typing.Sequence[str]] = None ) -> None: self._options[name] = _Option(name, typespec, default, help, choices) self.changed.send(self, updated={name}) @contextlib.contextmanager def rollback(self, updated, reraise=False): old = copy.deepcopy(self._options) try: yield except exceptions.OptionsError as e: # Notify error handlers self.errored.send(self, exc=e) # Rollback self.__dict__["_options"] = old self.changed.send(self, updated=updated) if reraise: raise e def subscribe(self, func, opts): """ Subscribe a callable to the .changed signal, but only for a specified list of options. The callable should accept arguments (options, updated), and may raise an OptionsError. The event will automatically be unsubscribed if the callable goes out of scope. """ for i in opts: if i not in self._options: raise exceptions.OptionsError("No such option: %s" % i) # We reuse blinker's safe reference functionality to cope with weakrefs # to bound methods. func = blinker._saferef.safe_ref(func) @functools.wraps(func) def _call(options, updated): if updated.intersection(set(opts)): f = func() if f: f(options, updated) else: self.changed.disconnect(_call) # Our wrapper function goes out of scope immediately, so we have to set # weakrefs to false. This means we need to keep our own weakref, and # clean up the hook when it's gone. self.changed.connect(_call, weak=False) def __eq__(self, other): if isinstance(other, OptManager): return self._options == other._options return False def __deepcopy__(self, memodict = None): o = OptManager() o.__dict__["_options"] = copy.deepcopy(self._options, memodict) return o __copy__ = __deepcopy__ def __getattr__(self, attr): if attr in self._options: return self._options[attr].current() else: raise AttributeError("No such option: %s" % attr) def __setattr__(self, attr, value): # This is slightly tricky. We allow attributes to be set on the instance # until we have an _options attribute. After that, assignment is sent to # the update function, and will raise an error for unknown options. opts = self.__dict__.get("_options") if not opts: super().__setattr__(attr, value) else: self.update(**{attr: value}) def keys(self): return set(self._options.keys()) def items(self): return self._options.items() def __contains__(self, k): return k in self._options def reset(self): """ Restore defaults for all options. """ for o in self._options.values(): o.reset() self.changed.send(self, updated=set(self._options.keys())) def update_known(self, **kwargs): """ Update and set all known options from kwargs. Returns a dictionary of unknown options. """ known, unknown = {}, {} for k, v in kwargs.items(): if k in self._options: known[k] = v else: unknown[k] = v updated = set(known.keys()) if updated: with self.rollback(updated, reraise=True): for k, v in known.items(): self._options[k].set(v) self.changed.send(self, updated=updated) return unknown def update_defer(self, **kwargs): unknown = self.update_known(**kwargs) self.deferred.update(unknown) def update(self, **kwargs): u = self.update_known(**kwargs) if u: raise KeyError("Unknown options: %s" % ", ".join(u.keys())) def setter(self, attr): """ Generate a setter for a given attribute. This returns a callable taking a single argument. """ if attr not in self._options: raise KeyError("No such option: %s" % attr) def setter(x): setattr(self, attr, x) return setter def toggler(self, attr): """ Generate a toggler for a boolean attribute. This returns a callable that takes no arguments. """ if attr not in self._options: raise KeyError("No such option: %s" % attr) o = self._options[attr] if o.typespec != bool: raise ValueError("Toggler can only be used with boolean options") def toggle(): setattr(self, attr, not getattr(self, attr)) return toggle def default(self, option: str) -> typing.Any: return self._options[option].default def has_changed(self, option): """ Has the option changed from the default? """ return self._options[option].has_changed() def merge(self, opts): """ Merge a dict of options into this object. Options that have None value are ignored. Lists and tuples are appended to the current option value. """ toset = {} for k, v in opts.items(): if v is not None: if isinstance(v, (list, tuple)): toset[k] = getattr(self, k) + v else: toset[k] = v self.update(**toset) def __repr__(self): options = pprint.pformat(self._options, indent=4).strip(" {}") if "\n" in options: options = "\n " + options + "\n" return "{mod}.{cls}({{{options}}})".format( mod=type(self).__module__, cls=type(self).__name__, options=options ) def set(self, *spec, defer=False): """ Takes a list of set specification in standard form (option=value). Options that are known are updated immediately. If defer is true, options that are not known are deferred, and will be set once they are added. """ vals = {} unknown = {} for i in spec: parts = i.split("=", maxsplit=1) if len(parts) == 1: optname, optval = parts[0], None else: optname, optval = parts[0], parts[1] if optname in self._options: vals[optname] = self.parse_setval(self._options[optname], optval) else: unknown[optname] = optval if defer: self.deferred.update(unknown) elif unknown: raise exceptions.OptionsError("Unknown options: %s" % ", ".join(unknown.keys())) self.update(**vals) def process_deferred(self): """ Processes options that were deferred in previous calls to set, and have since been added. """ update = {} for optname, optval in self.deferred.items(): if optname in self._options: optval = self.parse_setval(self._options[optname], optval) update[optname] = optval self.update(**update) for k in update.keys(): del self.deferred[k] def parse_setval(self, o: _Option, optstr: typing.Optional[str]) -> typing.Any: """ Convert a string to a value appropriate for the option type. """ if o.typespec in (str, typing.Optional[str]): return optstr elif o.typespec in (int, typing.Optional[int]): if optstr: try: return int(optstr) except ValueError: raise exceptions.OptionsError("Not an integer: %s" % optstr) elif o.typespec == int: raise exceptions.OptionsError("Option is required: %s" % o.name) else: return None elif o.typespec == bool: if optstr == "toggle": return not o.current() if not optstr or optstr == "true": return True elif optstr == "false": return False else: raise exceptions.OptionsError( "Boolean must be \"true\", \"false\", or have the value " "omitted (a synonym for \"true\")." ) elif o.typespec == typing.Sequence[str]: if not optstr: return [] else: return getattr(self, o.name) + [optstr] raise NotImplementedError("Unsupported option type: %s", o.typespec) def make_parser(self, parser, optname, metavar=None, short=None): """ Auto-Create a command-line parser entry for a named option. If the option does not exist, it is ignored. """ if optname not in self._options: return o = self._options[optname] def mkf(l, s): l = l.replace("_", "-") f = ["--%s" % l] if s: f.append("-" + s) return f flags = mkf(optname, short) if o.typespec == bool: g = parser.add_mutually_exclusive_group(required=False) onf = mkf(optname, None) offf = mkf("no-" + optname, None) # The short option for a bool goes to whatever is NOT the default if short: if o.default: offf = mkf("no-" + optname, short) else: onf = mkf(optname, short) g.add_argument( *offf, action="store_false", dest=optname, ) g.add_argument( *onf, action="store_true", dest=optname, help=o.help ) parser.set_defaults(**{optname: None}) elif o.typespec in (int, typing.Optional[int]): parser.add_argument( *flags, action="store", type=int, dest=optname, help=o.help, metavar=metavar, ) elif o.typespec in (str, typing.Optional[str]): parser.add_argument( *flags, action="store", type=str, dest=optname, help=o.help, metavar=metavar, choices=o.choices ) elif o.typespec == typing.Sequence[str]: parser.add_argument( *flags, action="append", type=str, dest=optname, help=o.help + " May be passed multiple times.", metavar=metavar, choices=o.choices, ) else: raise ValueError("Unsupported option type: %s", o.typespec) def dump_dicts(opts, keys: typing.List[str]=None): """ Dumps the options into a list of dict object. Return: A list like: { "anticache": { type: "bool", default: false, value: true, help: "help text"} } """ options_dict = {} keys = keys if keys else opts.keys() for k in sorted(keys): o = opts._options[k] t = typecheck.typespec_to_str(o.typespec) option = { 'type': t, 'default': o.default, 'value': o.current(), 'help': o.help, 'choices': o.choices } options_dict[k] = option return options_dict ,Traceback (most recent call last): File "C:\Users\Admin\Downloads\cursor-manager-main\.venv\Lib\site-packages\seleniumwire\thirdparty\mitmproxy\optmanager.py", line 9, in <module> import blinker._saferef ModuleNotFoundError: No module named 'blinker._saferef'
最新发布
08-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值