bpy.ops.preferences.addon_enable() only checks for changes in __init__.py; Problem for multi-file add-ons
#66924
Closed
opened 4 years ago by NumesSanguis-3
·
22 comments
No Branch/Tag Specified
main
asset-shelf
brush-assets-project
blender-v2.93-release
blender-v3.3-release
blender-v3.4-release
xr-dev
blender-v3.2-release
blender-v3.1-release
screenshots-manual
gltf_vtree
blender-v2.83-release
blender-v3.0-release
xr-controller-support
studio-sprite-fright
asset-browser-poselib
blender-v2.92-release
blender-v2.91-release
blender-v2.90-release
greasepencil-addon
xr-world-navigation
soc-2019-openxr
blender-v2.82-release
blender-v2.81-release
filebrowser_redesign
blender-v2.80-release
blender2.7
blender-v2.79b-release
blender-v2.79a-release
blender-v2.79-release
fbx_experiments
blender-v2.78b-release
collada-2
blender-v2.78-release
rigify_fixes
fbx_io_export_ignore_parents
v2.93.14
v3.3.3
v2.93.13
v2.93.12
v3.4.1
v3.3.2
v3.4.0
v3.3.1
v2.93.11
v3.3.0
v3.2.2
v2.93.10
v3.2.1
v3.2.0
v2.83.20
v2.93.9
v3.1.2
v3.1.1
v3.1.0
v2.83.19
v2.93.8
v3.0.1
v2.93.7
v3.0.0
v2.93.6
v2.93.5
v2.83.18
v2.93.4
v2.93.3
v2.83.17
v2.93.2
v2.93.1
v2.83.16
v2.93.0
v2.83.15
v2.83.14
v2.83.13
v2.92.0
v2.83.12
v2.91.2
v2.83.10
v2.91.0
v2.83.9
v2.83.8
v2.83.7
v2.90.1
v2.83.6
v2.90.0
v2.83.5
v2.83.4
v2.83.3
v2.83.2
v2.83.1
v2.83
v2.82a
v2.82
v2.81a
v2.81
v2.80
v2.80-rc3
v2.80-rc2
v2.80-rc1
v2.79b
v2.79a
v2.79
v2.79-rc2
v2.79-rc1
v2.78b
v2.78a
v2.78
v2.78-rc2
v2.78-rc1
v2.77a
v2.77
v2.77-rc2
v2.77-rc1
v2.76a
v2.76
v2.76-rc3
v2.76-rc1
v2.75
v2.75-rc2
v2.75-rc1
v2.74
v2.74-rc4
v2.74-rc3
v2.74-rc2
v2.74-rc1
v2.73a
v2.73
v2.73-rc1
v2.72
v2.72-rc1
v2.71
v2.71-rc1
v2.70a
v2.70
v2.70-rc
v2.68
v2.67b
v2.67a
v2.67
v2.66a
v2.66
v2.65a
v2.65
v2.64a
v2.64
v2.63a
v2.63
v2.62
v2.61
v2.60a
v2.53
v2.54
v2.55
v2.56
v2.56a
v2.57
v2.57a
v2.57b
v2.58
v2.58a
v2.59
v2.60
v2.69
Labels
Apply labels
Clear labels
good first issue
legacy module/Animation & Rigging
legacy module/Core
legacy module/Eevee & Viewport
legacy module/Grease Pencil
legacy module/Modeling
legacy module/Nodes & Physics
legacy module/Pipeline, Assets & IO
legacy module/Platforms, Builds, Tests & Devices
legacy module/Python API
legacy module/Rendering & Cycles
legacy module/Sculpt, Paint & Texture
legacy module/User Interface
legacy module/VFX & Video
legacy project/2.81
legacy project/2.82
legacy project/2.83
legacy project/2.90
legacy project/2.92
legacy project/2.93
legacy project/3.0
legacy project/3.1
legacy project/3.2
legacy project/3.4
legacy project/Add-ons (BF-Blender)
legacy project/Add-ons (Community)
legacy project/Alembic
legacy project/Animation & Rigging
legacy project/Asset Browser
legacy project/Automated Testing
legacy project/BF Blender: 2.8
legacy project/BF Blender: After Release
legacy project/BF Blender: Next
legacy project/BF Blender: Regressions
legacy project/BF Blender: Unconfirmed
legacy project/Blender 2.70
legacy project/Blender Cloud
legacy project/Code Quest
legacy project/Collada
legacy project/Compositing
legacy project/Core
legacy project/Cycles
legacy project/Datablocks and Libraries
legacy project/Dependency Graph
legacy project/Documentation
legacy project/EEVEE & Viewport
legacy project/Freestyle
legacy project/Game Data Conversion
legacy project/Game Engine
legacy project/Game Physics
legacy project/Game Python
legacy project/Game UI
legacy project/Geometry Nodes
legacy project/Good First Issue
legacy project/Grease Pencil
legacy project/Images & Movies
legacy project/Import/Export
legacy project/Infrastructure: Blender Buildbot
legacy project/Infrastructure: Blender Web Assets
legacy project/Infrastructure: Websites
legacy project/Modeling
legacy project/Modifiers
legacy project/Motion Tracking
legacy project/Nodes
legacy project/Nodes & Physics
legacy project/OpenGL Error
legacy project/Overrides
legacy project/Papercut
legacy project/Physics
legacy project/Pillar
legacy project/Pipeline, Assets & I/O
legacy project/Platform: Linux
legacy project/Platform: macOS
legacy project/Platforms, Builds, Tests & Devices
legacy project/Platform: Windows
legacy project/Python API
legacy project/Render & Cycles
legacy project/Render Pipeline
legacy project/Sculpt, Paint & Texture
legacy project/Straightforward Issue
legacy project/Text Editor
legacy project/Tracker Curfew
legacy project/Translations
legacy project/USD
legacy project/User Interface
legacy project/UV Editing
legacy project/VFX & Video
legacy project/Video Sequencer
legacy project/Virtual Reality
papercut
Priority › High
Priority › Low
Priority › Normal
Priority › Unbreak Now!
Status › Archived
Status › Confirmed
Status › Duplicate
Status › Needs Information from Developers
Status › Needs Information from User
Status › Needs Triage
Status › Resolved
straightforward issue
Type › Bug
Type › Design
Type › Known Issue
Type › Patch
Type › Report
Type › To Do
No Label
good first issue
legacy module/Animation & Rigging
legacy module/Core
legacy module/Eevee & Viewport
legacy module/Grease Pencil
legacy module/Modeling
legacy module/Nodes & Physics
legacy module/Pipeline, Assets & IO
legacy module/Platforms, Builds, Tests & Devices
legacy module/Python API
legacy module/Rendering & Cycles
legacy module/Sculpt, Paint & Texture
legacy module/User Interface
legacy module/VFX & Video
legacy project/2.81
legacy project/2.82
legacy project/2.83
legacy project/2.90
legacy project/2.92
legacy project/2.93
legacy project/3.0
legacy project/3.1
legacy project/3.2
legacy project/3.4
legacy project/Add-ons (BF-Blender)
legacy project/Add-ons (Community)
legacy project/Alembic
legacy project/Animation & Rigging
legacy project/Asset Browser
legacy project/Automated Testing
legacy project/BF Blender: 2.8
legacy project/BF Blender: After Release
legacy project/BF Blender: Next
legacy project/BF Blender: Regressions
legacy project/BF Blender: Unconfirmed
legacy project/Blender 2.70
legacy project/Blender Cloud
legacy project/Code Quest
legacy project/Collada
legacy project/Compositing
legacy project/Core
legacy project/Cycles
legacy project/Datablocks and Libraries
legacy project/Dependency Graph
legacy project/Documentation
legacy project/EEVEE & Viewport
legacy project/Freestyle
legacy project/Game Data Conversion
legacy project/Game Engine
legacy project/Game Physics
legacy project/Game Python
legacy project/Game UI
legacy project/Geometry Nodes
legacy project/Good First Issue
legacy project/Grease Pencil
legacy project/Images & Movies
legacy project/Import/Export
legacy project/Infrastructure: Blender Buildbot
legacy project/Infrastructure: Blender Web Assets
legacy project/Infrastructure: Websites
legacy project/Modeling
legacy project/Modifiers
legacy project/Motion Tracking
legacy project/Nodes
legacy project/Nodes & Physics
legacy project/OpenGL Error
legacy project/Overrides
legacy project/Papercut
legacy project/Physics
legacy project/Pillar
legacy project/Pipeline, Assets & I/O
legacy project/Platform: Linux
legacy project/Platform: macOS
legacy project/Platforms, Builds, Tests & Devices
legacy project/Platform: Windows
legacy project/Python API
legacy project/Render & Cycles
legacy project/Render Pipeline
legacy project/Sculpt, Paint & Texture
legacy project/Straightforward Issue
legacy project/Text Editor
legacy project/Tracker Curfew
legacy project/Translations
legacy project/USD
legacy project/User Interface
legacy project/UV Editing
legacy project/VFX & Video
legacy project/Video Sequencer
legacy project/Virtual Reality
papercut
Priority › High
Priority › Low
Priority › Normal
Priority › Unbreak Now!
Status › Archived
Status › Confirmed
Status › Duplicate
Status › Needs Information from Developers
Status › Needs Information from User
Status › Needs Triage
Status › Resolved
straightforward issue
Type › Bug
Type › Design
Type › Known Issue
Type › Patch
Type › Report
Type › To Do
Milestone
Set milestone
Clear milestone
No items
No Milestone
Projects
Set Project
Clear projects
No project
Assignees
Assign users
Clear assignees
No Assignees
8 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-addons#66924
Reference in new issue
There is no content yet.
Delete Branch '%!s(<nil>)'
Deleting a branch is permanent. It CANNOT be undone. Continue?
No
Yes
Symptoms
When you're developing an add-on existing out of multiple files on a disk, you want to reload your add-on many times to include the changes you made.
This works fine when you make a modification in
__init__.pyand callbpy.ops.preferences.addon_enable(module='your_module'), as you will see:"module changed on disk: 'path/to/file.py' reloading...".However, if you make a change in another module, e.g.
your_module_props.py, and calladdon_enable(), nothing is triggered. You will only see{'FINISHED'}.If you afterwards make a change to
__init__.py, the previous changes you made toyour_module_props.pyare seen by Blender this time when you calladdon_enable().Likely culprit
I believe the culprit is here: https://developer.blender.org/diffusion/B/browse/master/release/scripts/modules/addon_utils.py$325
These lines of code only check if the main file (
__init__.py) has changed.Possible solutions
One of the following:
Importance
Any medium/large add-on that follows proper code conventions to prevent spaghetti code will use multiple files. This limited check to only
__init__.pyseverely slows down app development, as we cannot do a quick reload. Instead we have to make a minimal change to__init__.pyto trigger the reload, or restart Blender every time we have made a code modification.Added subscriber: @NumesSanguis-3
To test if the check
if mtime_orig != mtime_new:is indeed the problem, I made an operator (simplified version of the originaladdon_enable(): developer.blender.org/diffusion/B/browse/master/release/scripts/modules/addon_utils.py$327) with that removed:and indeed, the add-on properly reloads now.
So I would suggest solution 2 in the main post.
Added subscriber: @dr.sybren
Changed status from 'Open' to: 'Archived'
Fortunately, this is not as big an issue as you describe. The code you linked is only used when enabling an add-on; the issue you describe seems to assume the way to reload an add-on is to disable and enable it.
Reloading your add-on can be done via the
bpy.ops.script.reload()operator which was bound to F8 in Blender 2.79; it's now available with the F3 menu (search for 'reload scripts') and you can create your own keyboard binding if you want. Multi-file addons need reloading support, which is quite easy to do; see this slide and the following slides or watch my Blender Conference 2016 workshop on the subject.Thank you @dr.sybren ,
bpy.ops.script.reload()indeed reloads all add-ons. I hadif "bpy" in locals():check to reload add-ons, but that wasn't triggered by my code, because__init__.pydidn't change.While luckily indeed a smaller issue than I assumed, I think it's nota solved one.
bpy.ops.script.reload()instead ofbpy.ops.preferences.addon_enable(module='your_module')I would assume the most knowledgeable Python programmers are active here, and therefore it seemsbpy.ops.script.reload()is not common knowledge. This is more a documentation issue, so I created an issue about this here: https:*developer.blender.org/T67387bpy.ops.script.reload()reloads ALL add-ons. If one of these add-ons is producing a error / warning, it will pollute the output/logs for the add-on you're actually try to develop. Also, if (multiple) non-relevant add-on(s) are slow at initializing, it will slow down the development process. Possible solutions I could think of:bpy.ops.script.reload(module_name=None), and only reload all when either None or no argument is passed.bpy.ops.preferences.addon_enable(module='your_module')intended for reloading specific add-ons by remove / extend the check if only__init__.pyfile changed.Added subscriber: @ideasman42
For development, you can:
Checking the date on the init file isn't meant to be a comprehensive check of the entire package.
Not all of them, and not all the time. Just search the Python API documentation for "reload script" and you'll find the
bpy.ops.script.reload()operator. Granted, it's not documented very well.Well, if you keep multiple non-relevant add-ons enabled while you're developing, I don't think this is an issue with reloading. I think it's an issue between keyboard & chair.
You could even add this code to an operator in your add-on and bind it to a menu item or button, then it's literally a one-click reload for only your add-on.
Added subscriber: @geckoman
I have created a workaround to this problem.
Example init.py:
someclassandsomemodulewill stay up-to-date when reloading addon withbpy.ops.preferences.addon_enable()and withbpy.ops.script.reload().Don't use the
from X import Ysyntax to import individual classes, that'll make reloading more cumbersome (as you've seen). If you just import (sub)modules you avoid the need for thatreload_class()function.That's good advice. I've gotten so used to just Googling things and usually finding the answer on stackoverflow, I forgot about direct searching.
For some reason Google doesn't index the Blender documentation, which would probably trouble more newcomers to Blender.
While in most case you'd be right, there are people who develop add-ons, that rely on / add functionality to add-ons of others. It is not always possible to merge this into 2 add-ons.
You could say, you could help speed-up that add-on, but some add-on creators are satisfied with their solution of whatever reason they have to not accept your contribution.
Also, it's possible that the add-on you rely on is good, but only requires a long initialization time (e.g. setup TCP connections to programs outside Blender, not so weird if you want to visualize data from a Robot).
The situation at the moment is:
bpy.ops.preferences.addon_enable(module='your_module'))bpy.ops.script.reload())Is it a huge problem? Not really. However, to me it feels like poor design that you can't just reload 1 add-on. Even if in most cases reloading all add-ons won't be much of a slowdown.
Would you say it makes sense if there is a function that can reload a (list of) specific add-ons? Given it's not too much effort to implement.
p.s. Could someone point me to the reload script?
importlibdoesn't find me anything on https://developer.blender.org/diffusion/B/browse/master/site:https://developer.blender.org/ importlibdoesn't show up anything either.p.p.s
Asked for referencing the code by making the function names on the documentation page clickable: https://developer.blender.org/T67674
Yeah, I did this. Is slightly less smooth if you're bugs are in the registering of the modules, which breaks the unloading, although that could have been because of me using
addon_enable:')This issue was referenced by blender/blender@ee4ec69b28
Changed status from 'Archived' to: 'Resolved'
Added subscriber: @antoniov
Changed status from 'Resolved' to: 'Open'
Sorry, closed by error.
Changed status from 'Open' to: 'Archived'
Added subscriber: @JosephDavies
Added subscriber: @1029910278
Recently , I notice that use reload() will destory the socket connection(when it became complex) on win. (win 10054 error)