Blender crashes when assigning materials from script - is it a bug?

I wrote a script. In one part of the script, there is this line:

base_object.data.materials.append (changeable_material)

Whenever I try to run the script, Blender just shuts down, immediately, without any error or anything, within a fraction of a second.

base_object is a cube generated by the script, changeable_material is a precreated material. I don't have much experience with Blender scripting.

Is this a mistake in my code or a bug? If not a bug, how do I fix it?

Edit:

Relevant parts of the script:

import bpy

matrix_size = 3

matrix = []
cubes = []
materials = []
matrix_range = range (matrix_size)

changeable_material = bpy.data.materials.get("Material")

material_value = 0

for i in range (matrix_size):
matrix.append([])
cubes.append ([])
materials.append (changeable_material.copy ())
materials [-1].node_tree.nodes.get("Value").outputs [0].default_value = material_value
material_value += 1 / matrix_size
for j in range (matrix_size):
matrix [-1].append ((i * j) % matrix_size)
cubes [-1].append (0)

(...)

#removes all unused materials
for material in bpy.data.materials:
if (not (material.users)):
bpy.data.materials.remove(material)

base_object = bpy.context.object
base_object.name = "base cube"
base_object.data.materials.append (changeable_material)

bpy.context.scene.objects.active = base_object

(...)

for i in range (matrix_size):
for j in range (matrix_size):
if cubes [i][j].data.materials:
cubes [i][j].data.materials[0] = materials [matrix [i][j]]


Here is the whole:

import bpy

matrix_size = 3

(...)

materials = []
matrix_range = range (matrix_size)

changeable_material = bpy.data.materials.get("Material")

material_value = 0

for i in range (matrix_size):
(...)
materials.append (changeable_material.copy ())
materials [-1].node_tree.nodes.get("Value").outputs [0].default_value = material_value
material_value += 1 / matrix_size
for j in range (matrix_size):
matrix [-1].append ((i * j) % matrix_size)
cubes [-1].append (0)

bpy.ops.object.select_all(action = "SELECT")

for i in bpy.data.objects:
if ((i.type == "CAMERA") or (i.type == "LAMP") or (i.name == "Material_Holder")):
i.select = False
bpy.ops.object.delete()

#removes all unused materials
for material in bpy.data.materials:
if (not (material.users)):
bpy.data.materials.remove(material)

base_object = bpy.context.object
base_object.name = "base cube"
base_object.data.materials.append (changeable_material)

base_object.scale = (0.5, 0.5, 0.5)

bpy.context.scene.objects.active = base_object

arrayOne = base_object.modifiers.new (name = "arrayOne", type = "ARRAY")
arrayOne.count = matrix_size
arrayTwo = base_object.modifiers.new (name = "arrayTwo", type = "ARRAY")
arrayTwo.count = matrix_size
arrayTwo.relative_offset_displace [0] = 0
arrayTwo.relative_offset_displace [1] = 1

bpy.ops.object.modifier_apply (modifier = "arrayOne")
bpy.ops.object.modifier_apply (modifier = "arrayTwo")

base_object.select = True
bpy.ops.mesh.separate (type = "LOOSE")

for i in bpy.data.objects:
if ("cube" in i.name):
bpy.ops.object.select_all(action = "DESELECT")
i.select = True
bpy.ops.object.origin_set (type = "ORIGIN_CENTER_OF_MASS")
cubes [int (i.location [0])][int (i.location [1])] = i

for i in range (matrix_size):
for j in range (matrix_size):
if cubes [i][j].data.materials:
cubes [i][j].data.materials[0] = materials [matrix [i][j]]

• You should probably post your relevant code, for others to check... – m.ardito Oct 17 '18 at 16:46
• The line is correct assuming the variables contain correct information. The issue must be in another part of the code. Without seeing the code it is impossible to say what is wrong. – Martynas Žiemys Oct 17 '18 at 17:53
• Try reducing the code to the minimal amount needed to reproduce the crash. Usually that gives you more insight, and also saves us from having to understand all of your stuff. – dr. Sybren Oct 18 '18 at 5:43
• Agree with comment above, or post full code(or a link to).The collection bpy.data.objects is all objects in the blend file which may be linked to context scene, another scene or no scene whatsoever. Suggest using context.scene.objects instead. Also to set an object to active scene.objects.active = ob as well as ob.select = True before calling an operator like origin set. An object can be active and not selected. – batFINGER Oct 18 '18 at 6:37

If the object with the name 'Material_Holder' does not have the material referenced by the variable changeable_material, that material will get removed (in block with the comment #removes all unused materials). There would be problem if later this (removed) material is appended to any object (base_object.data.materials.append (changeable_material)). The crash could be related to this.
So if the changeable_material is needed later in the code, the condition should be if (not (material.users)) and material is not changeable_material before calling remove.