Regression: Nodes: Selection of node affected on sorting -> correctness validation of links #107473

Closed
opened 2023-04-29 22:23:18 +02:00 by Roman Markov · 0 comments

System Information
Operating system: Windows-10-10.0.19044-SP0 64 Bits
Graphics card: GeForce GTX 760M/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 425.31

Blender Version
Broken: version: 3.5.0 Alpha, branch: master, commit date: 2022-11-22 00:01, hash: rB89349067b6f5
Worked: version: 3.5.0 Alpha, branch: master, commit date: 2022-11-21 01:31, hash: rB7a6cdeb24279

Potentially caused by: be1745425c

Short description of error
bpy.types.NodeLink.is_valid is inconsistent in the newer versions of Blender when the output socket is hidden. Depends on whether or not the input socket owner is active. The invalid status of the link remains after the blend file reloading. The link is expected to be valid. Including when purely created via python.

Exact steps for others to reproduce the error

Automated script:

The script will pip install pytest into site.getusersitepackages().

  1. Edit blenders paths
  2. Run the script
Script
import typing

def ensure_site_packages(packages: list, directory: str):
    """ 
    `packages`: list of tuples (<import name>, <pip name>)
    `directory`: a folder for site packages, will be created if does not exist and added to `sys.path`
    """

    if not packages:
        return

    import bpy
    import os
    import sys
    import importlib
    import importlib.util

    os.makedirs(directory, exist_ok = True)

    if not directory in sys.path:
        sys.path.append(directory)

    modules_to_install = [module[1] for module in packages if not importlib.util.find_spec(module[0])]
    if not modules_to_install:
        return

    if bpy.app.version < (2,91,0):
        python_binary = bpy.app.binary_path_python
    else:
        python_binary = sys.executable

    import subprocess
    subprocess.run([python_binary, '-m', 'ensurepip'], check=True)
    subprocess.run([python_binary, '-m', 'pip', 'install', *modules_to_install, "--target", directory], check=True)

    importlib.invalidate_caches()

def is_in_blender():
    try:
        import bpy
        return bool(bpy.app.version) and bool(bpy.app.binary_path)
    except:
        return False


def call_with_override(override: typing.Dict[str, typing.Any], func: typing.Callable, *args, **kwargs):

    import bpy
    from bpy import context

    _override: typing.Dict[str, typing.Any] = context.copy()
    _override.update(override)

    # new
    if bpy.app.version > (3,2,0):
        with context.temp_override(**_override):
            return func(*args, **kwargs)
    # old
    else:
        return func(_override, *args, **kwargs)


def get_mat():
    import bpy

    material = bpy.data.materials.new('test_mat')
    material.use_nodes = True
    material.use_fake_user = True

    material.node_tree.nodes.clear()

    return material

def select_all(material):

    import bpy

    area = bpy.data.window_managers[0].windows[0].screen.areas[0]
    area.type = 'NODE_EDITOR'

    if bpy.app.version > (2,80,0):
        area.ui_type = 'ShaderNodeTree'

    space_data = area.spaces[0]

    space_data.node_tree = material.node_tree

    override = bpy.context.copy()
    override['area'] = area
    override['space_data'] = space_data

    call_with_override(override, bpy.ops.node.select_all, action = 'SELECT')

def test_no_active():

    material = get_mat()
    nodes = material.node_tree.nodes
    links = material.node_tree.links

    xyz = nodes.new('ShaderNodeCombineXYZ')
    math = nodes.new('ShaderNodeVectorMath')

    link = links.new(xyz.inputs['X'], math.outputs['Value'])

    assert link.is_valid

def test_no_active_visible_socket():

    material = get_mat()
    nodes = material.node_tree.nodes
    links = material.node_tree.links

    xyz = nodes.new('ShaderNodeCombineXYZ')
    math = nodes.new('ShaderNodeVectorMath')

    math.operation = 'DOT_PRODUCT'

    link = links.new(xyz.inputs['X'], math.outputs['Value'])

    assert link.is_valid

def test_active_xyz():

    material = get_mat()
    name = material.name

    import bpy

    node_tree = material.node_tree
    nodes = node_tree.nodes
    links = node_tree.links

    xyz = nodes.new('ShaderNodeCombineXYZ')
    math = nodes.new('ShaderNodeVectorMath')

    nodes.active = xyz
    select_all(material)

    link = links.new(xyz.inputs['X'], math.outputs['Value'])

    assert link.is_valid

def test_active_math():

    material = get_mat()
    node_tree = material.node_tree
    nodes = material.node_tree.nodes
    links = material.node_tree.links

    xyz = nodes.new('ShaderNodeCombineXYZ')
    math = nodes.new('ShaderNodeVectorMath')

    nodes.active = math
    select_all(material)

    link = links.new(xyz.inputs['X'], math.outputs['Value'])

    assert link.is_valid


if __name__ == "__main__" and is_in_blender():

    import site
    ensure_site_packages([("pytest", "pytest")], directory = site.getusersitepackages())

    import pytest

    raise SystemExit(pytest.main(['-svv', __file__]))


blenders = [
    r'blender',
    r'C:\blender\blender-3.1.2-windows-x64\blender.exe',
    r'C:\blender\blender-3.6.0-alpha+main.e078419c9c12-windows.amd64-release\blender.exe',
    r'C:\Program Files (x86)\Steam\steamapps\common\Blender\blender.exe',
    r'D:\games\SteamLibrary\steamapps\common\blender_293\blender.exe',
    r'D:\games\SteamLibrary\steamapps\common\blender-2.83.13-windows64\blender.exe',
    r'D:\source\software\blender\blender-2.82-windows64\blender.exe',
    r'D:\games\SteamLibrary\steamapps\common\blender-2.79.0-git.e045fe53f1b0-windows64\blender.exe',
]

if __name__ == '__main__' and not is_in_blender():
    import subprocess

    for blender in blenders:
        subprocess.run([blender, '--version'])
        subprocess.run([blender, '--python-exit-code', '1',  '--factory-startup', '--python', __file__])
        
Output
Blender 3.1.2
        build date: 2022-03-31
        build time: 23:39:57  
        build commit date: 2022-03-31
        build commit time: 17:40
        build hash: cc66d1020c3b
        build platform: Windows
        build type: release
        build c flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj /Zc:inline -openmp
        build c++ flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3  /EHsc /nologo /J /Gd /MP /EHsc 
/bigobj /Zc:inline /permissive- /Zc:twoPhase- -openmp /Zc:__cplusplus
        build link flags: /MACHINE:X64  /SUBSYSTEM:CONSOLE /STACK:2097152 /ignore:4049 /ignore:4217 /ignore:4221
        build system: CMake
================================================== test session starts ==================================================
platform win32 -- Python 3.10.2, pytest-7.3.1, pluggy-1.0.0 -- C:\blender\blender-3.1.2-windows-x64\3.1\python\bin\python.EXE
cachedir: .pytest_cache
rootdir: C:\Users\user\vscode_scripts
plugins: cov-4.0.0
collected 4 items

test_230429_213225.py::test_no_active PASSED
test_230429_213225.py::test_no_active_visible_socket PASSED
test_230429_213225.py::test_active_xyz PASSED
test_230429_213225.py::test_active_math PASSED

=================================================== 4 passed in 0.03s =================================================== 
Saved session recovery to 'C:\Users\user\AppData\Local\Temp\quit.blend'
Blender 3.6.0 Alpha
        build date: 2023-04-15
        build time: 01:04:04
        build commit date: 2023-04-14
        build commit time: 22:58
        build hash: e078419c9c12
        build platform: Windows
        build type: release
        build c flags: /W3 /w34062 /w34100 /w34115 /w34189 /w35038 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /wd4848 /we4013 /we4133 /we4431 /we4033 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj /Zc:inline -openmp
        build c++ flags: /W3 /w34062 /w34100 /w34115 /w34189 /w35038 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /wd4848 /we4013 /we4133 /we4431 /we4033 /DWIN32 /D_WINDOWS /W3  /EHsc /nologo /J /Gd /MP /EHsc /bigobj /Zc:inline /permissive- /Zc:twoPhase- -openmp /Zc:__cplusplus
        build link flags: /MACHINE:X64  /SUBSYSTEM:CONSOLE /STACK:2097152 /ignore:4049 /ignore:4217 /ignore:4221
        build system: CMake
================================================== test session starts ==================================================
platform win32 -- Python 3.10.9, pytest-7.3.1, pluggy-1.0.0 -- C:\blender\blender-3.6.0-alpha+main.e078419c9c12-windows.amd64-release\3.6\python\bin\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\user\vscode_scripts
plugins: cov-4.0.0
collected 4 items

test_230429_213225.py::test_no_active FAILED
test_230429_213225.py::test_no_active_visible_socket PASSED
test_230429_213225.py::test_active_xyz PASSED
test_230429_213225.py::test_active_math FAILED

======================================================= FAILURES ======================================================== 
____________________________________________________ test_no_active _____________________________________________________

    def test_no_active():

        material = get_mat()
        nodes = material.node_tree.nodes
        links = material.node_tree.links

        xyz = nodes.new('ShaderNodeCombineXYZ')
        math = nodes.new('ShaderNodeVectorMath')

        link = links.new(xyz.inputs['X'], math.outputs['Value'])

>       assert link.is_valid
E       AssertionError: assert False
E        +  where False = bpy.data.materials['test_mat'].node_tree.is_valid

test_230429_213225.py:105: AssertionError
___________________________________________________ test_active_math ____________________________________________________ 

    def test_active_math():

        material = get_mat()
        node_tree = material.node_tree
        nodes = material.node_tree.nodes
        links = material.node_tree.links

        xyz = nodes.new('ShaderNodeCombineXYZ')
        math = nodes.new('ShaderNodeVectorMath')

        nodes.active = math
        select_all(material)

        link = links.new(xyz.inputs['X'], math.outputs['Value'])

>       assert link.is_valid
E       AssertionError: assert False
E        +  where False = bpy.data.materials['test_mat.003'].node_tree.is_valid

test_230429_213225.py:158: AssertionError
================================================ short test summary info ================================================ 
FAILED test_230429_213225.py::test_no_active - AssertionError: assert False
FAILED test_230429_213225.py::test_active_math - AssertionError: assert False
============================================== 2 failed, 2 passed in 0.25s ============================================== 
Saved session recovery to "C:\Users\user\AppData\Local\Temp\quit.blend"
Blender 3.5.1
        build date: 2023-04-24
        build time: 23:56:35
        build commit date: 2023-04-24
        build commit time: 18:11
        build hash: e1ccd9d4a1d3
        build platform: Windows
        build type: release
        build c flags: /W3 /w34062 /w34115 /w34189 /w35038 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /wd4848 /we4013 /we4133 /we4431 /we4033 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj /Zc:inline -openmp
        build c++ flags: /W3 /w34062 /w34115 /w34189 /w35038 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /wd4848 /we4013 /we4133 /we4431 /we4033 /DWIN32 /D_WINDOWS /W3  /EHsc /nologo /J /Gd /MP /EHsc /bigobj /Zc:inline /permissive- /Zc:twoPhase- -openmp /Zc:__cplusplus
        build link flags: /MACHINE:X64  /SUBSYSTEM:CONSOLE /STACK:2097152 /ignore:4049 /ignore:4217 /ignore:4221
        build system: CMake
================================================== test session starts ==================================================
platform win32 -- Python 3.10.9, pytest-7.3.1, pluggy-1.0.0 -- C:\Program Files (x86)\Steam\steamapps\common\Blender\3.5\python\bin\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\user\vscode_scripts
plugins: cov-4.0.0
collected 4 items

test_230429_213225.py::test_no_active FAILED
test_230429_213225.py::test_no_active_visible_socket PASSED
test_230429_213225.py::test_active_xyz PASSED
test_230429_213225.py::test_active_math FAILED

======================================================= FAILURES ========================================================
____________________________________________________ test_no_active _____________________________________________________ 

    def test_no_active():

        material = get_mat()
        nodes = material.node_tree.nodes
        links = material.node_tree.links

        xyz = nodes.new('ShaderNodeCombineXYZ')
        math = nodes.new('ShaderNodeVectorMath')

        link = links.new(xyz.inputs['X'], math.outputs['Value'])

>       assert link.is_valid
E       AssertionError: assert False
E        +  where False = bpy.data.materials['test_mat'].node_tree.is_valid

test_230429_213225.py:105: AssertionError
___________________________________________________ test_active_math ____________________________________________________ 

    def test_active_math():

        material = get_mat()
        node_tree = material.node_tree
        nodes = material.node_tree.nodes
        links = material.node_tree.links

        xyz = nodes.new('ShaderNodeCombineXYZ')
        math = nodes.new('ShaderNodeVectorMath')

        nodes.active = math
        select_all(material)

        link = links.new(xyz.inputs['X'], math.outputs['Value'])

>       assert link.is_valid
E       AssertionError: assert False
E        +  where False = bpy.data.materials['test_mat.003'].node_tree.is_valid

test_230429_213225.py:158: AssertionError
================================================ short test summary info ================================================ 
FAILED test_230429_213225.py::test_no_active - AssertionError: assert False
FAILED test_230429_213225.py::test_active_math - AssertionError: assert False
============================================== 2 failed, 2 passed in 0.24s ==============================================
Saved session recovery to 'C:\Users\user\AppData\Local\Temp\quit.blend'
Blender 2.93.1
        build date: 2021-06-22
        build time: 23:47:42
        build commit date: 2021-06-22
        build commit time: 05:57
        build hash: 1b8d33b18c2f
        build platform: Windows
        build type: release
        build c flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj -openmp
        build c++ flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3  /EHsc /nologo /J /Gd /MP /EHsc 
/bigobj /permissive- /Zc:twoPhase- -openmp /std:c++17 /Zc:__cplusplus
        build link flags: /MACHINE:X64  /SUBSYSTEM:CONSOLE /STACK:2097152 /ignore:4049 /ignore:4217 /ignore:4221
        build system: CMake
================================================== test session starts ==================================================
platform win32 -- Python 3.9.2, pytest-7.3.1, pluggy-1.0.0 -- D:\games\SteamLibrary\steamapps\common\blender_293\2.93\python\bin\python.EXE
cachedir: .pytest_cache
rootdir: C:\Users\user\vscode_scripts
collected 4 items                                                                                                         

test_230429_213225.py::test_no_active PASSED
test_230429_213225.py::test_no_active_visible_socket PASSED
test_230429_213225.py::test_active_xyz PASSED
test_230429_213225.py::test_active_math PASSED

=================================================== 4 passed in 0.02s =================================================== 
Saved session recovery to 'C:\Users\user\AppData\Local\Temp\quit.blend'
Blender 2.83.13
        build date: 2021-03-09
        build time: 23:50:43
        build commit date: 2021-03-09
        build commit time: 07:21
        build hash: bb5004673085
        build platform: Windows
        build type: Release
        build c flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj -openmp
        build c++ flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /GR /EHsc /nologo /J /Gd /MP /EHsc /bigobj /permissive- /Zc:twoPhase- -openmp
        build link flags: /MACHINE:X64  /SUBSYSTEM:CONSOLE /STACK:2097152,70656 /INCREMENTAL:NO  /ignore:4049 /ignore:4217 /ignore:4221
        build system: CMake
found bundled python: D:\games\SteamLibrary\steamapps\common\blender-2.83.13-windows64\2.83\python
================================================== test session starts ==================================================
platform win32 -- Python 3.7.4, pytest-7.3.1, pluggy-1.0.0 -- D:\games\SteamLibrary\steamapps\common\blender-2.83.13-windows64\blender.exe
cachedir: .pytest_cache
rootdir: C:\Users\user\vscode_scripts
collected 4 items                                                                                                         

test_230429_213225.py::test_no_active PASSED
test_230429_213225.py::test_no_active_visible_socket PASSED
test_230429_213225.py::test_active_xyz PASSED
test_230429_213225.py::test_active_math PASSED

=================================================== 4 passed in 0.02s =================================================== 
Saved session recovery to 'C:\Users\user\AppData\Local\Temp\quit.blend'
Blender 2.82 (sub 7)
        build date: 2020-02-13
        build time: 01:56:46
        build commit date: 2020-02-12
        build commit time: 16:20
        build hash: 77d23b0bd76f
        build platform: Windows
        build type: Release
        build c flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj -openmp
        build c++ flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /GR /EHsc /nologo /J /Gd /MP /EHsc /bigobj -openmp
        build link flags: /MACHINE:X64  /SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO  /ignore:4049 /ignore:4217 /ignore:4221
        build system: CMake
found bundled python: D:\source\software\blender\blender-2.82-windows64\2.82\python
================================================== test session starts ==================================================
platform win32 -- Python 3.7.4, pytest-7.3.1, pluggy-1.0.0 -- D:\source\software\blender\blender-2.82-windows64\blender.exe
cachedir: .pytest_cache
rootdir: C:\Users\user\vscode_scripts
collected 4 items                                                                                                         

test_230429_213225.py::test_no_active PASSED
test_230429_213225.py::test_no_active_visible_socket PASSED
test_230429_213225.py::test_active_xyz PASSED
test_230429_213225.py::test_active_math PASSED

=================================================== 4 passed in 0.02s =================================================== 
Saved session recovery to 'C:\Users\user\AppData\Local\Temp\quit.blend'
Blender 2.79 (sub 7)
        build date: 28/07/2019
        build time: 17:48
        build commit date: 2019-06-27
        build commit time: 10:41
        build hash: e045fe53f1b0
        build platform: Windows
        build type: Release
        build c flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP -openmp
        build c++ flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /GR /EHsc /nologo /J /Gd /MP /EHsc -openmp
        build link flags: /MACHINE:X64  /SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO  /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib  /ignore:4049 /ignore:4217 /ignore:4221
        build system: CMake
AL lib: (EE) UpdateDeviceParams: Failed to set 44100hz, got 48000hz instead
found bundled python: D:\games\SteamLibrary\steamapps\common\blender-2.79.0-git.e045fe53f1b0-windows64\2.79\python
================================================== test session starts ==================================================
platform win32 -- Python 3.7.0, pytest-7.3.1, pluggy-1.0.0 -- D:\games\SteamLibrary\steamapps\common\blender-2.79.0-git.e045fe53f1b0-windows64\blender.exe
cachedir: .pytest_cache
rootdir: C:\Users\user\vscode_scripts
collected 4 items

test_230429_213225.py::test_no_active PASSED
test_230429_213225.py::test_no_active_visible_socket PASSED
test_230429_213225.py::test_active_xyz PASSED
test_230429_213225.py::test_active_math PASSED

=================================================== 4 passed in 0.02s ===================================================
Saved session recovery to 'C:\tmp\quit.blend'
Error: Not freed memory blocks: 2, total unfreed memory 0.000427 MB

Manually:

See the attached video.

  1. Open is_valid_test.blend
  2. Select the vector math node and run the Text script
  3. Select the XYZ node and run the Text script
**System Information** Operating system: Windows-10-10.0.19044-SP0 64 Bits Graphics card: GeForce GTX 760M/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 425.31 **Blender Version** Broken: version: 3.5.0 Alpha, branch: master, commit date: 2022-11-22 00:01, hash: `rB89349067b6f5` Worked: version: 3.5.0 Alpha, branch: master, commit date: 2022-11-21 01:31, hash: `rB7a6cdeb24279` Potentially caused by: https://projects.blender.org/blender/blender/commit/be1745425cad0a87f6ea35aaacf78bf4404a91ac **Short description of error** `bpy.types.NodeLink.is_valid` is inconsistent in the newer versions of Blender when the output socket is hidden. Depends on whether or not the input socket owner is active. The invalid status of the link remains after the blend file reloading. The link is expected to be valid. Including when purely created via python. **Exact steps for others to reproduce the error** ### Automated script: #### The script will pip install `pytest` into `site.getusersitepackages()`. 1. Edit `blenders` paths 2. Run the script <details> <summary>Script</summary> ```py import typing def ensure_site_packages(packages: list, directory: str): """ `packages`: list of tuples (<import name>, <pip name>) `directory`: a folder for site packages, will be created if does not exist and added to `sys.path` """ if not packages: return import bpy import os import sys import importlib import importlib.util os.makedirs(directory, exist_ok = True) if not directory in sys.path: sys.path.append(directory) modules_to_install = [module[1] for module in packages if not importlib.util.find_spec(module[0])] if not modules_to_install: return if bpy.app.version < (2,91,0): python_binary = bpy.app.binary_path_python else: python_binary = sys.executable import subprocess subprocess.run([python_binary, '-m', 'ensurepip'], check=True) subprocess.run([python_binary, '-m', 'pip', 'install', *modules_to_install, "--target", directory], check=True) importlib.invalidate_caches() def is_in_blender(): try: import bpy return bool(bpy.app.version) and bool(bpy.app.binary_path) except: return False def call_with_override(override: typing.Dict[str, typing.Any], func: typing.Callable, *args, **kwargs): import bpy from bpy import context _override: typing.Dict[str, typing.Any] = context.copy() _override.update(override) # new if bpy.app.version > (3,2,0): with context.temp_override(**_override): return func(*args, **kwargs) # old else: return func(_override, *args, **kwargs) def get_mat(): import bpy material = bpy.data.materials.new('test_mat') material.use_nodes = True material.use_fake_user = True material.node_tree.nodes.clear() return material def select_all(material): import bpy area = bpy.data.window_managers[0].windows[0].screen.areas[0] area.type = 'NODE_EDITOR' if bpy.app.version > (2,80,0): area.ui_type = 'ShaderNodeTree' space_data = area.spaces[0] space_data.node_tree = material.node_tree override = bpy.context.copy() override['area'] = area override['space_data'] = space_data call_with_override(override, bpy.ops.node.select_all, action = 'SELECT') def test_no_active(): material = get_mat() nodes = material.node_tree.nodes links = material.node_tree.links xyz = nodes.new('ShaderNodeCombineXYZ') math = nodes.new('ShaderNodeVectorMath') link = links.new(xyz.inputs['X'], math.outputs['Value']) assert link.is_valid def test_no_active_visible_socket(): material = get_mat() nodes = material.node_tree.nodes links = material.node_tree.links xyz = nodes.new('ShaderNodeCombineXYZ') math = nodes.new('ShaderNodeVectorMath') math.operation = 'DOT_PRODUCT' link = links.new(xyz.inputs['X'], math.outputs['Value']) assert link.is_valid def test_active_xyz(): material = get_mat() name = material.name import bpy node_tree = material.node_tree nodes = node_tree.nodes links = node_tree.links xyz = nodes.new('ShaderNodeCombineXYZ') math = nodes.new('ShaderNodeVectorMath') nodes.active = xyz select_all(material) link = links.new(xyz.inputs['X'], math.outputs['Value']) assert link.is_valid def test_active_math(): material = get_mat() node_tree = material.node_tree nodes = material.node_tree.nodes links = material.node_tree.links xyz = nodes.new('ShaderNodeCombineXYZ') math = nodes.new('ShaderNodeVectorMath') nodes.active = math select_all(material) link = links.new(xyz.inputs['X'], math.outputs['Value']) assert link.is_valid if __name__ == "__main__" and is_in_blender(): import site ensure_site_packages([("pytest", "pytest")], directory = site.getusersitepackages()) import pytest raise SystemExit(pytest.main(['-svv', __file__])) blenders = [ r'blender', r'C:\blender\blender-3.1.2-windows-x64\blender.exe', r'C:\blender\blender-3.6.0-alpha+main.e078419c9c12-windows.amd64-release\blender.exe', r'C:\Program Files (x86)\Steam\steamapps\common\Blender\blender.exe', r'D:\games\SteamLibrary\steamapps\common\blender_293\blender.exe', r'D:\games\SteamLibrary\steamapps\common\blender-2.83.13-windows64\blender.exe', r'D:\source\software\blender\blender-2.82-windows64\blender.exe', r'D:\games\SteamLibrary\steamapps\common\blender-2.79.0-git.e045fe53f1b0-windows64\blender.exe', ] if __name__ == '__main__' and not is_in_blender(): import subprocess for blender in blenders: subprocess.run([blender, '--version']) subprocess.run([blender, '--python-exit-code', '1', '--factory-startup', '--python', __file__]) ``` </details> <details> <summary>Output</summary> ```cmd Blender 3.1.2 build date: 2022-03-31 build time: 23:39:57 build commit date: 2022-03-31 build commit time: 17:40 build hash: cc66d1020c3b build platform: Windows build type: release build c flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj /Zc:inline -openmp build c++ flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /EHsc /nologo /J /Gd /MP /EHsc /bigobj /Zc:inline /permissive- /Zc:twoPhase- -openmp /Zc:__cplusplus build link flags: /MACHINE:X64 /SUBSYSTEM:CONSOLE /STACK:2097152 /ignore:4049 /ignore:4217 /ignore:4221 build system: CMake ================================================== test session starts ================================================== platform win32 -- Python 3.10.2, pytest-7.3.1, pluggy-1.0.0 -- C:\blender\blender-3.1.2-windows-x64\3.1\python\bin\python.EXE cachedir: .pytest_cache rootdir: C:\Users\user\vscode_scripts plugins: cov-4.0.0 collected 4 items test_230429_213225.py::test_no_active PASSED test_230429_213225.py::test_no_active_visible_socket PASSED test_230429_213225.py::test_active_xyz PASSED test_230429_213225.py::test_active_math PASSED =================================================== 4 passed in 0.03s =================================================== Saved session recovery to 'C:\Users\user\AppData\Local\Temp\quit.blend' Blender 3.6.0 Alpha build date: 2023-04-15 build time: 01:04:04 build commit date: 2023-04-14 build commit time: 22:58 build hash: e078419c9c12 build platform: Windows build type: release build c flags: /W3 /w34062 /w34100 /w34115 /w34189 /w35038 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /wd4848 /we4013 /we4133 /we4431 /we4033 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj /Zc:inline -openmp build c++ flags: /W3 /w34062 /w34100 /w34115 /w34189 /w35038 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /wd4848 /we4013 /we4133 /we4431 /we4033 /DWIN32 /D_WINDOWS /W3 /EHsc /nologo /J /Gd /MP /EHsc /bigobj /Zc:inline /permissive- /Zc:twoPhase- -openmp /Zc:__cplusplus build link flags: /MACHINE:X64 /SUBSYSTEM:CONSOLE /STACK:2097152 /ignore:4049 /ignore:4217 /ignore:4221 build system: CMake ================================================== test session starts ================================================== platform win32 -- Python 3.10.9, pytest-7.3.1, pluggy-1.0.0 -- C:\blender\blender-3.6.0-alpha+main.e078419c9c12-windows.amd64-release\3.6\python\bin\python.exe cachedir: .pytest_cache rootdir: C:\Users\user\vscode_scripts plugins: cov-4.0.0 collected 4 items test_230429_213225.py::test_no_active FAILED test_230429_213225.py::test_no_active_visible_socket PASSED test_230429_213225.py::test_active_xyz PASSED test_230429_213225.py::test_active_math FAILED ======================================================= FAILURES ======================================================== ____________________________________________________ test_no_active _____________________________________________________ def test_no_active(): material = get_mat() nodes = material.node_tree.nodes links = material.node_tree.links xyz = nodes.new('ShaderNodeCombineXYZ') math = nodes.new('ShaderNodeVectorMath') link = links.new(xyz.inputs['X'], math.outputs['Value']) > assert link.is_valid E AssertionError: assert False E + where False = bpy.data.materials['test_mat'].node_tree.is_valid test_230429_213225.py:105: AssertionError ___________________________________________________ test_active_math ____________________________________________________ def test_active_math(): material = get_mat() node_tree = material.node_tree nodes = material.node_tree.nodes links = material.node_tree.links xyz = nodes.new('ShaderNodeCombineXYZ') math = nodes.new('ShaderNodeVectorMath') nodes.active = math select_all(material) link = links.new(xyz.inputs['X'], math.outputs['Value']) > assert link.is_valid E AssertionError: assert False E + where False = bpy.data.materials['test_mat.003'].node_tree.is_valid test_230429_213225.py:158: AssertionError ================================================ short test summary info ================================================ FAILED test_230429_213225.py::test_no_active - AssertionError: assert False FAILED test_230429_213225.py::test_active_math - AssertionError: assert False ============================================== 2 failed, 2 passed in 0.25s ============================================== Saved session recovery to "C:\Users\user\AppData\Local\Temp\quit.blend" Blender 3.5.1 build date: 2023-04-24 build time: 23:56:35 build commit date: 2023-04-24 build commit time: 18:11 build hash: e1ccd9d4a1d3 build platform: Windows build type: release build c flags: /W3 /w34062 /w34115 /w34189 /w35038 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /wd4848 /we4013 /we4133 /we4431 /we4033 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj /Zc:inline -openmp build c++ flags: /W3 /w34062 /w34115 /w34189 /w35038 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /wd4848 /we4013 /we4133 /we4431 /we4033 /DWIN32 /D_WINDOWS /W3 /EHsc /nologo /J /Gd /MP /EHsc /bigobj /Zc:inline /permissive- /Zc:twoPhase- -openmp /Zc:__cplusplus build link flags: /MACHINE:X64 /SUBSYSTEM:CONSOLE /STACK:2097152 /ignore:4049 /ignore:4217 /ignore:4221 build system: CMake ================================================== test session starts ================================================== platform win32 -- Python 3.10.9, pytest-7.3.1, pluggy-1.0.0 -- C:\Program Files (x86)\Steam\steamapps\common\Blender\3.5\python\bin\python.exe cachedir: .pytest_cache rootdir: C:\Users\user\vscode_scripts plugins: cov-4.0.0 collected 4 items test_230429_213225.py::test_no_active FAILED test_230429_213225.py::test_no_active_visible_socket PASSED test_230429_213225.py::test_active_xyz PASSED test_230429_213225.py::test_active_math FAILED ======================================================= FAILURES ======================================================== ____________________________________________________ test_no_active _____________________________________________________ def test_no_active(): material = get_mat() nodes = material.node_tree.nodes links = material.node_tree.links xyz = nodes.new('ShaderNodeCombineXYZ') math = nodes.new('ShaderNodeVectorMath') link = links.new(xyz.inputs['X'], math.outputs['Value']) > assert link.is_valid E AssertionError: assert False E + where False = bpy.data.materials['test_mat'].node_tree.is_valid test_230429_213225.py:105: AssertionError ___________________________________________________ test_active_math ____________________________________________________ def test_active_math(): material = get_mat() node_tree = material.node_tree nodes = material.node_tree.nodes links = material.node_tree.links xyz = nodes.new('ShaderNodeCombineXYZ') math = nodes.new('ShaderNodeVectorMath') nodes.active = math select_all(material) link = links.new(xyz.inputs['X'], math.outputs['Value']) > assert link.is_valid E AssertionError: assert False E + where False = bpy.data.materials['test_mat.003'].node_tree.is_valid test_230429_213225.py:158: AssertionError ================================================ short test summary info ================================================ FAILED test_230429_213225.py::test_no_active - AssertionError: assert False FAILED test_230429_213225.py::test_active_math - AssertionError: assert False ============================================== 2 failed, 2 passed in 0.24s ============================================== Saved session recovery to 'C:\Users\user\AppData\Local\Temp\quit.blend' Blender 2.93.1 build date: 2021-06-22 build time: 23:47:42 build commit date: 2021-06-22 build commit time: 05:57 build hash: 1b8d33b18c2f build platform: Windows build type: release build c flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj -openmp build c++ flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /EHsc /nologo /J /Gd /MP /EHsc /bigobj /permissive- /Zc:twoPhase- -openmp /std:c++17 /Zc:__cplusplus build link flags: /MACHINE:X64 /SUBSYSTEM:CONSOLE /STACK:2097152 /ignore:4049 /ignore:4217 /ignore:4221 build system: CMake ================================================== test session starts ================================================== platform win32 -- Python 3.9.2, pytest-7.3.1, pluggy-1.0.0 -- D:\games\SteamLibrary\steamapps\common\blender_293\2.93\python\bin\python.EXE cachedir: .pytest_cache rootdir: C:\Users\user\vscode_scripts collected 4 items test_230429_213225.py::test_no_active PASSED test_230429_213225.py::test_no_active_visible_socket PASSED test_230429_213225.py::test_active_xyz PASSED test_230429_213225.py::test_active_math PASSED =================================================== 4 passed in 0.02s =================================================== Saved session recovery to 'C:\Users\user\AppData\Local\Temp\quit.blend' Blender 2.83.13 build date: 2021-03-09 build time: 23:50:43 build commit date: 2021-03-09 build commit time: 07:21 build hash: bb5004673085 build platform: Windows build type: Release build c flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj -openmp build c++ flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /GR /EHsc /nologo /J /Gd /MP /EHsc /bigobj /permissive- /Zc:twoPhase- -openmp build link flags: /MACHINE:X64 /SUBSYSTEM:CONSOLE /STACK:2097152,70656 /INCREMENTAL:NO /ignore:4049 /ignore:4217 /ignore:4221 build system: CMake found bundled python: D:\games\SteamLibrary\steamapps\common\blender-2.83.13-windows64\2.83\python ================================================== test session starts ================================================== platform win32 -- Python 3.7.4, pytest-7.3.1, pluggy-1.0.0 -- D:\games\SteamLibrary\steamapps\common\blender-2.83.13-windows64\blender.exe cachedir: .pytest_cache rootdir: C:\Users\user\vscode_scripts collected 4 items test_230429_213225.py::test_no_active PASSED test_230429_213225.py::test_no_active_visible_socket PASSED test_230429_213225.py::test_active_xyz PASSED test_230429_213225.py::test_active_math PASSED =================================================== 4 passed in 0.02s =================================================== Saved session recovery to 'C:\Users\user\AppData\Local\Temp\quit.blend' Blender 2.82 (sub 7) build date: 2020-02-13 build time: 01:56:46 build commit date: 2020-02-12 build commit time: 16:20 build hash: 77d23b0bd76f build platform: Windows build type: Release build c flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP /bigobj -openmp build c++ flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /wd4661 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /GR /EHsc /nologo /J /Gd /MP /EHsc /bigobj -openmp build link flags: /MACHINE:X64 /SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /ignore:4049 /ignore:4217 /ignore:4221 build system: CMake found bundled python: D:\source\software\blender\blender-2.82-windows64\2.82\python ================================================== test session starts ================================================== platform win32 -- Python 3.7.4, pytest-7.3.1, pluggy-1.0.0 -- D:\source\software\blender\blender-2.82-windows64\blender.exe cachedir: .pytest_cache rootdir: C:\Users\user\vscode_scripts collected 4 items test_230429_213225.py::test_no_active PASSED test_230429_213225.py::test_no_active_visible_socket PASSED test_230429_213225.py::test_active_xyz PASSED test_230429_213225.py::test_active_math PASSED =================================================== 4 passed in 0.02s =================================================== Saved session recovery to 'C:\Users\user\AppData\Local\Temp\quit.blend' Blender 2.79 (sub 7) build date: 28/07/2019 build time: 17:48 build commit date: 2019-06-27 build commit time: 10:41 build hash: e045fe53f1b0 build platform: Windows build type: Release build c flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /nologo /J /Gd /MP -openmp build c++ flags: /W3 /w34062 /w34115 /w34189 /wd4018 /wd4146 /wd4065 /wd4127 /wd4181 /wd4200 /wd4244 /wd4267 /wd4305 /wd4800 /wd4828 /wd4996 /we4013 /we4133 /we4431 /w35038 /DWIN32 /D_WINDOWS /W3 /GR /EHsc /nologo /J /Gd /MP /EHsc -openmp build link flags: /MACHINE:X64 /SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib /ignore:4049 /ignore:4217 /ignore:4221 build system: CMake AL lib: (EE) UpdateDeviceParams: Failed to set 44100hz, got 48000hz instead found bundled python: D:\games\SteamLibrary\steamapps\common\blender-2.79.0-git.e045fe53f1b0-windows64\2.79\python ================================================== test session starts ================================================== platform win32 -- Python 3.7.0, pytest-7.3.1, pluggy-1.0.0 -- D:\games\SteamLibrary\steamapps\common\blender-2.79.0-git.e045fe53f1b0-windows64\blender.exe cachedir: .pytest_cache rootdir: C:\Users\user\vscode_scripts collected 4 items test_230429_213225.py::test_no_active PASSED test_230429_213225.py::test_no_active_visible_socket PASSED test_230429_213225.py::test_active_xyz PASSED test_230429_213225.py::test_active_math PASSED =================================================== 4 passed in 0.02s =================================================== Saved session recovery to 'C:\tmp\quit.blend' Error: Not freed memory blocks: 2, total unfreed memory 0.000427 MB ``` </details> ### Manually: See the attached video. 1. Open `is_valid_test.blend` 2. Select the vector math node and run the `Text` script 3. Select the XYZ node and run the `Text` script
Roman Markov added the
Priority
Normal
Status
Needs Triage
Type
Report
labels 2023-04-29 22:23:18 +02:00
Iliya Katushenock changed title from Inconsistent behavior of `bpy.types.NodeLink.is_valid` to Regression: Nodes: Selection of node affected on sorting -> correctness validation 2023-04-29 23:11:02 +02:00
Iliya Katushenock changed title from Regression: Nodes: Selection of node affected on sorting -> correctness validation to Regression: Nodes: Selection of node affected on sorting -> correctness validation of links 2023-04-29 23:11:50 +02:00
Iliya Katushenock self-assigned this 2023-05-06 00:13:53 +02:00
Blender Bot added
Status
Resolved
and removed
Status
Confirmed
labels 2023-06-09 14:19:44 +02:00
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#107473
No description provided.