python-rubik icon indicating copy to clipboard operation
python-rubik copied to clipboard

import utils problem

Open imrrobat opened this issue 3 years ago • 2 comments

when i want to import: from rubik_solver import utils

this error happened: Traceback (most recent call last): File "<pyshell#1>", line 1, in from rubik_solver import utils File "C:\Users---\AppData\Local\Programs\Python\Python310\lib\site-packages\rubik_solver\utils.py", line 4, in from past.builtins import basestring File "C:\Users---\AppData\Local\Programs\Python\Python310\lib\site-packages\past\builtins_init_.py", line 43, in from past.builtins.noniterators import (filter, map, range, reduce, zip) File "C:\Users---\AppData\Local\Programs\Python\Python310\lib\site-packages\past\builtins\noniterators.py", line 24, in from past.types import basestring File "C:\Users---\AppData\Local\Programs\Python\Python310\lib\site-packages\past\types_init_.py", line 25, in from .oldstr import oldstr File "C:\Users---\AppData\Local\Programs\Python\Python310\lib\site-packages\past\types\oldstr.py", line 5, in from collections import Iterable ImportError: cannot import name 'Iterable' from 'collections' (C:\Users---\AppData\Local\Programs\Python\Python310\lib\collections_init_.py)

imrrobat avatar Jul 24 '22 18:07 imrrobat

Change collections to collections.abc https://stackoverflow.com/questions/72032032/importerror-cannot-import-name-iterable-from-collections-in-python

andrebhu avatar Nov 08 '22 16:11 andrebhu

Unfortunately, the version of future that this repo has pinned was affected by one of the breaking changes PSF pushed out with Python 3.9.

Without having to refactor any packaging or risk breaking anything else, here's a quick fix to make everything immediately "just work" if you're trying to run this on your system

import os, sys, re, pathlib
from tempfile import NamedTemporaryFile

def fix_pythonrubik_issue14(past):
    assert sys.version_info < (4, )
    p, = past.__path__
    r = re.compile(r'^((?:from collections import )([\w, ]+))$', re.M)
    for file in _recurse_files(pathlib.Path(p)):
        body = file.read_text(errors='surrogateescape')
        m = r.search(body)
        if m:
            newbody = r.sub(
                lambda m: 'try:\n    %s\nexcept ImportError:\n    from collections.abc import %s' % m.groups(),
                body)
            _safe_overwrite(newbody, file)

def _recurse_files(d):
    for dirpath, dirnames, filenames in os.walk(d):
        for filename in filenames:
            yield pathlib.Path(os.path.join(dirpath, filename))

def _safe_overwrite(src_content, dest):
    # Reduce risk of corrupting system libraries
    mode = 'w+b' if isinstance(src_content, bytes) else 'w+t'
    with NamedTemporaryFile(mode, dir=dest.parent, delete=False) as f:
        f_path = pathlib.Path(f.name)
        f.write(src_content)
        f.flush()
    f_path.replace(dest)  # This is as atomic as it gets, I think

if __name__ == '__main__':
    import time
    try:
        import past.builtins
        print("No need to patch")
    except ImportError:
        print("There was a problem importing!")
        print("Going to try to patch this problem.")
        print("PRESS CTRL_C WITHIN TEN SECONDS IF YOU DON'T WANT TO ATTEMPT.")
        time.sleep(10)
        print("Patching...")
        import past
        fix_pythonrubik_issue14(past)
        import past.builtins
    print(repr(past.builtins), "OK")

James-E-A avatar May 04 '23 22:05 James-E-A