JacquesLucke / blender_vscode

Visual Studio Code extension for Blender development.
MIT License
570 stars 75 forks source link

AttributeError: 'bpy.app' object has no attribute 'binary_path_python' #80

Closed Lissanro closed 2 months ago

Lissanro commented 3 years ago

bpy.app.binary_path_python was deprecated in 2.91 and removed for 2.92 in favor of sys.executable by the following commit: https://developer.blender.org/rB6527a14cd2ceaaf529beae522ca594bb250b56c9 As a result, this extension stopped working because of the error on startup: AttributeError: 'bpy.app' object has no attribute 'binary_path_python'

Strange, but for me sys.executable returns path to the Blender executable:

>>> import sys
>>> sys.executable
'/home/lissanro/pkgs/blender/blender-2.92.0-cac8a7cddb56-linux64/blender'

I found https://blender.stackexchange.com/questions/139718/install-pip-and-packages-from-within-blender-os-independently where it is suggested to use sys.prefix instead, and my solution below is based on this suggestion. I do not know if using bpy.app.binary_path_python is necessary for compatibility with old Blender versions. If it isn't, the following change in environment.py could solve the issue:

import sys
python_path = next((Path(sys.prefix)/"bin").glob("python*"))

If it is necessary to use bpy.app.binary_path_python for old Blender versions, then the following code would work:

try:
    python_path = Path(bpy.app.binary_path_python)
except AttributeError:
    import sys
    python_path = next((Path(sys.prefix)/"bin").glob("python*"))

Since I'm not sure what is the best fix for this, I decided to open an issue instead of PR.

JacquesLucke commented 3 years ago

Thanks for looking into this. It was reported to me on Blender Chat a couple of minutes ago as well: https://blender.chat/channel/python?msg=hPpgYx5cfpZvrxpLg

The solution should be to simply use sys.executable for newer versions. If that does still return the path to Blender in latest master, you should make a bug report at https://developer.blender.org/.

gaiaclary commented 3 years ago

Here are the first few lines in environment.py with the modifications which fixed the issue for me:

import sys
import bpy
import addon_utils
from pathlib import Path

python_path = Path(sys.executable)
blender_path = Path(bpy.app.binary_path)
Lissanro commented 3 years ago

I do not think just using sys.executable is a good idea, this will break the extension for everyone who does not use latest Alpha version. Using sys.executable was the first thing I tried, but it did not work as expected. Today I decided to check again and upgraded to the latest master and sys.executable returns path to the Python executable. This allows to simplify my previous code like this:

try:
    python_path = Path(bpy.app.binary_path_python)
except AttributeError:
    import sys
    python_path = Path(sys.executable)

The code above will break the addon only for single nightly Alpha build, but all official releases and current master will work properly. So I think this is the best solution.

I do not know if sys.executable ever worked in versions lower than current 2.92 so I decided to try 2.90 and got the following:

>>> bpy.app.version_string
'2.90.0'
>>> import sys
>>> sys.executable
'/home/lissanro/pkgs/blender/blender-2.90.0-linux64/blender'

Just few days ago 2.92 Alpha also had the same behavior, sys.executable contained path to the Blender executable.

For comparison, with today's 2.92 latest Alpha build, sys.executable contains path to the Python executable:

>>> bpy.app.version_string
'2.92.0 Alpha'
>>> import sys
>>> sys.executable
'/home/lissanro/pkgs/blender/blender-2.92.0-316a5914bcc6-linux64/2.92/python/bin/python3.7m'
JacquesLucke commented 3 years ago

This still has to be updated at some point. But we are good for one more release: https://developer.blender.org/rBa1f46ac9dc71d66adced895a98f912a5d8440748

BrechtCorbeel commented 1 year ago

Here are the first few lines in environment.py with the modifications which fixed the issue for me:

import sys
import bpy
import addon_utils
from pathlib import Path

python_path = Path(sys.executable)
blender_path = Path(bpy.app.binary_path)

This one did wonders for me