You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit fefd033
Browse filesBrowse the repository at this point in the historyBrowse files
- shader-node-group snippet and procedural-materials skill: group.inputs/outputs.new
were removed in 4.0; use interface.new_socket on every supported version (#286)
- export_preset_unreal: scale object locations with scale so spacing grows 100x (#297)
- export presets, engine-export-presets skill, pipeline template, rules: one
transform_apply call; override selected_editable_objects, not selected_objects (#298)
- version-fact fixes: context-dict override removed in 4.0, Specular rename in 4.0,
5.2 LTS is current stable, Extensions primary since 4.2, vse Strip link and
hasattr guidance, dangling import comment, add-on template license/maintainer (#287)
Closes#286, closes#297, closes#298, closes#287
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: rules/prefer-temp-override-over-context-copy.mdc
+21-18Lines changed: 21 additions & 18 deletions
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,5 @@
1
1
---
2
-
description: Flag uses of `bpy.context.copy()` to override context for an operator call. The copy-and-pass pattern was deprecated in Blender 4.x and the override semantics were removed in 5.x. Use `bpy.context.temp_override(**overrides)` as a context manager instead.
2
+
description: Flag uses of `bpy.context.copy()` to override context for an operator call. Passing a context dict to an operator was deprecated in Blender 3.2 and removed in 4.0, so it already fails on the 4.5 LTS fallback. Use `bpy.context.temp_override(**overrides)` as a context manager instead.
3
3
alwaysApply: false
4
4
globs:
5
5
- "**/*.py"
@@ -9,15 +9,14 @@ standards-version: 1.10.0
9
9
# Prefer `temp_override` over `context.copy()`
10
10
11
11
`bpy.context.copy()` returns a dict snapshot of the current context. In
12
-
Blender 4.x and earlier it was common to mutate that dict and pass it as
12
+
Blender 3.x and earlier it was common to mutate that dict and pass it as
13
13
the first positional argument to an operator (`bpy.ops.x.y(ctx, ...)`)
14
14
to run the operator under a fabricated context. That mechanism was
15
-
deprecated in 4.x and the operator override semantics were removed in
16
-
5.x. The same code on 5.x either silently ignores the override or fails
17
-
with a confusing argument-type error.
15
+
deprecated in 3.2 and removed in 4.0. The same code on 4.0 and later,
16
+
including 4.5 LTS, fails with a confusing argument-type error.
18
17
19
18
The supported replacement is `bpy.context.temp_override(**overrides)`,
20
-
which works as a context manager and applies cleanly on both 4.5 LTS and
19
+
which works as a context manager and applies cleanly on 4.5 LTS and
21
20
5.x.
22
21
23
22
## What this rule flags
@@ -49,23 +48,28 @@ bpy.ops.object.delete({
49
48
})
50
49
```
51
50
52
-
Both forms run on 4.x with deprecation warnings. On 5.x they either no-op
53
-
the override silently or raise `TypeError: Calling operator "bpy.ops.object.delete"
51
+
Both forms ran with deprecation warnings on 3.2 to 3.6. On 4.0 and later
52
+
(4.5 LTS, 5.x) they raise `TypeError: Calling operator "bpy.ops.object.delete"
54
53
error, expected a string enum, not a dict`.
55
54
56
55
## Right
57
56
58
57
```python
59
58
import bpy
60
59
61
-
with bpy.context.temp_override(active_object=my_obj, selected_objects=[my_obj]):
60
+
with bpy.context.temp_override(active_object=my_obj, selected_editable_objects=[my_obj]):
62
61
bpy.ops.object.delete()
63
62
```
64
63
65
64
`temp_override` accepts the same keyword names as the keys you would
66
65
have put in the dict. It restores the previous context on exit, even
67
-
on exception. It is supported on 4.2+ and is the only override path
68
-
on 5.x.
66
+
on exception. It is supported on 3.2+ and is the only override path
67
+
on 4.0+.
68
+
69
+
Override the key the operator actually reads. `transform_apply` and
70
+
similar operators act on `selected_editable_objects`, so
71
+
`selected_objects=[obj]` alone does not narrow them to one object; use
72
+
`selected_editable_objects=[obj]`.
69
73
70
74
## When you also need a window override
71
75
@@ -84,19 +88,18 @@ with bpy.context.temp_override(window=window, area=area, region=region):
84
88
85
89
## Why it matters
86
90
87
-
The deprecated path silently drops the override on 5.x in many cases.
88
-
Code that "worked" on 4.x produces wrong results on 5.x without an
89
-
obvious failure. The user reports "my add-on broke after upgrade" and
90
-
the cause is a context override that is now ignored.
91
+
The dict-passing path was removed in 4.0, so code that "worked" on 3.x
92
+
raises on 4.5 LTS and 5.x. The user reports "my add-on broke after
93
+
upgrade" and the cause is a context override that no longer exists.
91
94
92
95
`temp_override` is the canonical, supported, and forward-compatible
93
-
replacement. There is no scenario in 5.x where the dict-passing form is
96
+
replacement. There is no scenario on 4.0+ where the dict-passing form is
tagline = "Short description, max 64 chars, no trailing period"
38
-
maintainer = "TMHSDigital <contact@example.com>"
38
+
maintainer = "Your Name <you@your-domain.example>"
39
39
type = "add-on"
40
40
41
41
blender_version_min = "4.5.0"
42
42
43
-
license = ["SPDX:MIT"]
43
+
license = ["SPDX:GPL-3.0-or-later"]
44
44
copyright = ["2026 TMHSDigital"]
45
45
```
46
46
@@ -199,7 +199,7 @@ def unregister():
199
199
200
200
## Compatibility paths
201
201
202
-
For libraries you want to be installable on both 4.5 LTS and 5.1, also keep `bl_info` for 4.5 fallback even though new submissions to the extensions platform require the manifest. Blender prefers the manifest when both are present.
202
+
For libraries you want to be installable on both 4.5 LTS and 5.2 LTS, also keep `bl_info` for 4.5 fallback even though new submissions to the extensions platform require the manifest. Blender prefers the manifest when both are present.
Copy file name to clipboardExpand all lines: skills/bl-info-migration/SKILL.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,7 +20,7 @@ Use this skill when the user:
20
20
21
21
Yes, with caveats.
22
22
23
-
-**In 5.1 stable**: `bl_info` is supported as a fallback for legacy add-ons. The Edit > Preferences > Add-ons panel still has "Install legacy Add-on" and recognizes `bl_info` dicts.
23
+
-**In 5.2 LTS (current stable; 5.1 is prior stable)**: `bl_info` is supported as a fallback for legacy add-ons. The Edit > Preferences > Add-ons panel still has "Install legacy Add-on" and recognizes `bl_info` dicts.
24
24
-**For the Extensions Platform** (extensions.blender.org and the new add-ons UI): you need a `blender_manifest.toml`. `bl_info` is ignored.
25
25
-**Dual format** is officially recognized: ship a `blender_manifest.toml` and keep the `bl_info` dict. The platform reads the manifest; legacy installers read `bl_info`. Both code paths work without conditional logic.
26
26
@@ -220,9 +220,9 @@ This produces a `.zip` in `dist\` that the user installs via Edit > Preferences
Copy file name to clipboardExpand all lines: skills/procedural-materials-and-shaders/SKILL.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -158,10 +158,10 @@ When the same subgraph appears across multiple materials, factor it into a `Shad
158
158
159
159
## Version correctness
160
160
161
-
| Topic | 4.5 LTS | 5.1 stable| Notes |
161
+
| Topic | 4.5 LTS | 5.1 / 5.2 LTS| Notes |
162
162
| --- | --- | --- | --- |
163
-
| Principled BSDF |`ShaderNodeBsdfPrincipled`| Same |Some inputs renamed in 5.0; `Specular` -> `Specular IOR Level`. Use string lookup with the 5.x name. |
164
-
| Node group socket interface |`group.inputs.new` /`group.outputs.new`|`group.interface.new_socket`| Different APIs, see snippet `shader-node-group.py`. |
163
+
| Principled BSDF |`ShaderNodeBsdfPrincipled`| Same |Inputs were renamed in 4.0 with the Principled v2 rewrite: `Specular` -> `Specular IOR Level` (see the 4.0 release notes, https://developer.blender.org/docs/release_notes/4.0/). Use string lookup with the 4.0+ name. |
164
+
| Node group socket interface |`group.interface.new_socket`|`group.interface.new_socket`|Same API on every supported version. `group.inputs.new` / `outputs.new` were removed in 4.0; see snippet `shader-node-group.py`. |
165
165
| EEVEE engine string |`'BLENDER_EEVEE_NEXT'`|`'BLENDER_EEVEE'`| Legacy EEVEE was removed in 4.2. EEVEE Next used the id `'BLENDER_EEVEE_NEXT'` on 4.2-4.5, then reclaimed the plain `'BLENDER_EEVEE'` id in 5.0. |
166
166
| Layered Textures | Not present | Not present in 5.1 | Roadmap pushed to 2027. Do not generate code referencing it. |
Copy file name to clipboardExpand all lines: skills/vse-python/SKILL.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -38,7 +38,7 @@ else:
38
38
strip.color = (0.85, 0.10, 0.22)
39
39
```
40
40
41
-
Branch on `bpy.app.version`, never on `bpy.app.version_string`. An empty `bpy_prop_collection` is falsy —`se.strips or se.sequences` silently falls through to the legacy accessor on an empty timeline. Always branch on `hasattr`.
41
+
Branch on the `bpy.app.version` tuple for known API boundaries (such as the 5.2 COLOR strip `width`/`height` bake), never on `bpy.app.version_string`. Pick the `.strips` vs `.sequences` accessor with `hasattr`, not version: an empty `bpy_prop_collection` is falsy, so`se.strips or se.sequences` silently falls through to the legacy accessor on an empty timeline.
42
42
43
43
## Accessor: `.strips` vs `.sequences`
44
44
@@ -152,6 +152,7 @@ A lone COLOR strip **does** honor `transform.scale_*` on 5.2. The break is media
0 commit comments