Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

magic conda fails in windows (re can not parse path) #14350

Open
gnosys-scrawford opened this issue Feb 20, 2024 · 2 comments
Open

magic conda fails in windows (re can not parse path) #14350

gnosys-scrawford opened this issue Feb 20, 2024 · 2 comments

Comments

@gnosys-scrawford
Copy link

In a jupyter notebook when trying to run conda or mamba as a magic command, in Windows, it fails. For example
%conda --version

The problem is that in IPython\core\magics\packaging.py, in _get_conda_like_executable there is

    match = re.search(
        rf"^#\s*cmd:\s*(?P<command>.*{executable})\s[create|install]",
        history,
        flags=re.MULTILINE,
    )

where executable is a Path object. In windows, this gets converted to a string with backslashes. re then tries to treat these backslashes as escape characters and fails. For example, when executable is 'c:\Users\me\mambaforge\envs\myenv\conda' the error will be error: incomplete escape \U at position 28

I believe the fix is to use executable.name instead of executable in the search string. This will emulate previous versions but I don't know if there are other considerations.

@ivanov
Copy link
Member

ivanov commented Feb 23, 2024

Thanks for your report, @gnosys-scrawford . I think doing executable.name would work only in some cases, and it would not work when executable located somewhere not in the PATH directories (or if there are mutliple executables with the same name in different directories on PATH, and the executable desired isn't the first one).

By the time the code you highlighted is executing, we're in a path that's commented as "Otherwise, attempt to extract the executable from conda history. "

executable = Path(sys.executable).parent / command
if executable.is_file():
return str(executable)
# Otherwise, attempt to extract the executable from conda history.
# This applies in any conda environment.
history = Path(sys.prefix, "conda-meta", "history").read_text(encoding="utf-8")
match = re.search(
rf"^#\s*cmd:\s*(?P<command>.*{executable})\s[create|install]",
history,
flags=re.MULTILINE,
)

Can you try instead of {executable} to do {str(executable)}? I think this would get around the escape issue.

The Python docs say

The string representation of a path is the raw filesystem path itself (in native form, e.g. with backslashes under Windows), which you can pass to any function taking a file path as a string:

>>> p = PurePath('/etc')
>>> str(p)
'/etc'
>>> p = PureWindowsPath('c:/Program Files')
>>> str(p)
'c:\\Program Files'

@gnosys-scrawford
Copy link
Author

Thanks for the response,

My suggestion was based primarily that before the latest commit, the search would take place just on the literal string "conda" (no absolute path), and the latest commit comment was just "Implement magic for mamba and micromamba" so switching to executable.name (actually, switching to command would be better) would achieve that specific goal of allowing "conda" or "mamba" or "micromamba". I could be wrong, but I don't think that including the path to conda when searching the environment history was intended as a bug fix.

I see that in every one of my environment history files, the path to mamba is
C:\\Users\\me\\mambaforge\\Scripts\\mamba for creating, instaling, updating, etc. It is never c:\Users\me\mambaforge\envs\myenv\mamba. If that copy of mamba exists, it would have already ben found by the earlier if executable.is_file(): statement and not reached the history search section of code.

Even when experimenting on a linux system, I tried creating an environment, activating it, then mamba install mamba so that a mamba executable was in the environment path, then mamba install numpy for example... in the history, it still showed cmd: /srv/conda/condabin/mamba install numpy not /srv/conda/envs/testenv/bin/mamba. This actually surprised me, as which mamba showed /srv/conda/envs/testenv/bin/mamba.

Oh also, I just noticed that the _get_conda_like_executable has command as a parameter but its docstring mentions executable as a parameter, so it's definitely plausible these terms got mixed up in the code!

That's a long-winded way of saying that I think changing {executable} to {command} in the re.search call would avoid the exception and make functionality closer to what it was before the latest update, which I think is what was intended.

If wanting to avoid the exception but keep the functionality of searching environment history with the path (not my recommendation):

executable is a Pathlib.WindowsPath not a Pathlib.PureWindowsPath (as required to run is_file()). But str(executable) still just has the single backslashes. So it would require something more, like type cast it str(PureWindowsPath(executable)) or do a string replace str(executable).replace('\\','\\\\').

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants