As each extension has it's own package, any modules it includes must be
imported as sub-modules. Warn if extensions are including themselves
in the sys.path as this breaks name-spacing of extensions.
Show these warnings in the add-on & extensions UI.
When the extensions add-on module was loaded before the add-on was
enabled, the module was detected as having changed since it had no
`__time__` member. Loading the add-on would then reload the module.
Resolve by setting the __time__ when first importing.
Previously add-ons were sorted by category & name, remove the category
only sorting by name since the category is no longer displayed and
isn't part of extension meta-data. Now the add-ons are sorted by name
(case insensitive).
Details:
- Store add-ons modules sorted to avoid having to sort on every redraw.
- addon_utils.modules() now returns an iterator.
Changes to an extensions manifest weren't accounted for.
This was particularly a problem for "System" extensions which aren't
intended to be managed inside Blender however the problem existed for
any changes made outside of Blender.
Now enabled extensions are checked on startup to ensure:
- They are compatible with Blender.
- The Python wheels are synchronized.
Resolves#123645.
Details:
- Any extension incompatibilities prevent the add-on being enabled
with a message printing the reason for it being disabled.
- Incompatible add-ons are kept enabled in the preferences to avoid
loosing their own preferences and allow for an upgrade to restore
compatibility.
- To avoid slowing down Blender's startup:
- Checks are skipped when no extensions are enabled
(as is the case for `--factory-startup` & running tests).
- Compatibility data is cached so in common case,
the cache is loaded and all enabled extensions `stat` their
manifests to detect changes without having to parse them.
- The cache is re-generated if any extensions change or the
Blender/Python version changes.
- Compatibility data is updated:
- On startup (when needed).
- On an explicit "Refresh Local"
(mainly for developers who may edit the manifest).
- When refreshing extensions after install/uninstall etc.
since an incompatible extensions may become compatible
after an update.
- When reloading preferences.
- Additional info is shown when the `--debug-python` is enabled,
if there are ever issues with the extension compatibility cache
generation not working as expected.
- The behavior for Python wheels has changed so they are only setup
when the extension is enabled. This was done to simplify startup
checks and has the benefit that an installed but disabled extension
never runs code - as the ability to install wheels means it could
have been imported from other scripts. It also means users can disable
an extension to avoid wheel version conflicts.
This does add the complication however that enabling add-on which is
an extension must first ensure it's wheels are setup.
See `addon_utils.extensions_refresh(..)`.
See code-comments for further details.
Provide a convenient way to access a writable directory for extensions.
This will typically be accessed via:
bpy.utils.extension_path_user(__package__, create=True)
This API is provided as some extensions on extensions.blender.org
are writing into the extensions own directory which is error prone:
- The extensions own directory is removed when upgrading.
- Users may not have write access to the extensions directory,
especially with "System" repositories which may be on shared network
drives for example.
These directories are only removed when:
- Uninstalling the extension.
- Removing the repository and its files.
All add-ons were being scanned at startup, while this didn't cause
errors it was noticeable with extensions where any errors in the
manifest were being reported at startup, even when running with
factory-startup (including blender's own tests).
Address two issues:
- The logic to "reset" add-ons, so as to match the preferences when
reverting or resetting preferences always ran on startup.
This occurred because a check for Python being initialized was
incorrectly used to detect that this wasn't the first time preferences
were being loaded (regression in [0]).
- Resetting add-ons scanned all add-ons (including disabled add-ons) to
ensure their module cache is up to date. Since this the cache is
lazily initialized, it's simpler to set it as uninitialized as
resetting the add-ons doesn't require the cached meta-data.
[0]: 497bc4d19977abc7b9e2c0f5024a23057e680954
The extensions spec says this should use semantic version,
so it should always start with X.Y.Z numbers.
Co-authored-by: Campbell Barton <campbell@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/122687
An extension's optional "tagline" field is equivalent to a legacy
add-on's "description". This allows exposing the tagline as a
description in `bl_info`.
The main goal of this change is to expose extension taglines to the
translations, since the legacy description was already extracted.
Pull Request: https://projects.blender.org/blender/blender/pulls/122327
The extensions system allows to extend Blender with connectivity to the internet. Right now it means Blender can
discover and install add-ons and themes directly from the internet, and notify users about their updates.
By default this is disabled (opt-in), and users can enable it the first time they try to install an extension or visit
the Prefences > Extensions tab. If this is enabled, Blender will automatically check for updates for
extensions.blender.org upon startup.
When will Blender access the remote repositories:
* Every time you open the Preferences → Extensions: ALL the enabled repositories get checked for the latest info (json)
* Every time you try to install by dragging: ALL the enabled repositories get checked for the latest info (json).
* Every time you start Blender: selected repositories get checked for the latest info (json).
------------------
From the Blender code point of view, this means that most of the add-ons and themes originally bundled with Blender
will now be available from the online platform, instead of bundled with Blender. The exception are add-ons which are
deemed core functionality which just happened to be written as Python add-ons.
Links:
* Original Extenesions Platform Announcement: https://code.blender.org/2022/10/blender-extensions-platform/
* Extensions website: https://extensions.blender.org/
* User Manual: https://docs.blender.org/manual/en/4.2/extensions/index.html#extensions-index
* Technical specifications: https://developer.blender.org/docs/features/extensions/
* Changes on add-ons bundling: https://devtalk.blender.org/t/changes-to-add-on-bundling-4-2-onwards/34593
------------------
This PR does the following:
* Move extensions out of experimental.
* No longer install `scripts/addons` & `scripts/addons_contrib`.
* Add `scripts/addons_core` to blender's repository.
These add-ons will still be bundled with Blender and will be always enabled in the future, with their preferences
moved to be more closely integrated with the rest of Blender. This will happen during the remaining bcon2 period.
For more details, see #121830
From scripts/addons:
* copy_global_transform.py
* hydra_storm
* io_anim_bvh
* io_curve_svg
* io_mesh_uv_layout
* io_scene_fbx
* io_scene_gltf2
* pose_library
* ui_translate
* viewport_vr_preview
Extra: bl_pkg (scripts/addons_contrib)
Note: The STL (legacy) add-on is going to be moved to the extensions platform. There is already a C++ version on core
which is enabled by default.
All the other add-ons are already available at extensions.blender.org. To use them you need to:
* Go to User Preferences > Extensions
* You will be greated with an "Online Extensions" message, click on "Enable Repository".
* Search the add-on you are looking for (e.g, Import Images as Planes).
* Click on Install
Over time their maintaince will be transferred over to the community so their development can carry on. If you used to
help maintain a bundled add-on please read: https://devtalk.blender.org/t/changes-to-add-on-bundling-4-2-onwards/34593
Ref: !121825
Copy modules before filtering `addon_modules` to avoid
change of dictionnary size during iterations. Otherwise errors
can be triggerd when running `python -m pytest test.py` since
it may modify the module dict.
Co-authored-by: Alexis-19 <alexis-19@noreply.localhost>
Pull Request: https://projects.blender.org/blender/blender/pulls/121100
When loading an add-on without a __file__ set the "cause" was empty.
Now the modules __path__ is included (when available) which points
to the path that failed to load to help with troubleshooting.
Although this error isn't specific to extensions, extensions containing
a blender_manifest.toml but no __init__.py would import a module
with the __file__ set to None.
While there is logic to handle this case, it didn't account for modules
already in sys.modules with __file__ set to None.
From a user perspective enabling the extension silently failed raising
an error on the second attempt to enable.
- Adding new repositories now differentiates between "Online" & "Local"
where adding a local repository doesn't prompt for a URL.
- Support removing repositories and their files (uses confirmation
defaulting to "Cancel" to avoid accidents).
- Show an error icon next to repositories that have invalid settings,
these repositories are now ignored until the settings are corrected,
required fields are highlighted red when they're unset & required.
- Rename "directory" to "custom_directory" since an automatic path is
used when not set - created in the users scripts directory.
- Use toggles for custom-directory & remote URL instead of relying on
the value to be left an empty string for alternative behavior.
Add-ons "bl_info" was supported for add-ons which weren't registered,
however the real modules weren't handled causing module_bl_info()
to return dummy values when an extensions add-ons module was passed in.
This caused the minimum Blender version check after enabling an add-on
to do nothing.
Now the "bl_info" from extension modules is ignored and the bl_info
is created on demand from the manifest.
- Add a warning when an extensions meta-data is missing.
- Remove the time-stamps from message that time-stamps have changes
since knowing the exact times isn't helpful.
- Rename info to bl_info, to avoid confusion with extensions manifest,
which should eventually be accessible in a similar way.
- Rename module_name to addon_module_name to avoid confusion with
extension repositories name-spaced modules.
- Clarify naming for TOML manifest.
This is needed so extensions repositories can reference
user-script directories without them having hard-coded paths
which will be invalid when upgrading a Blender version.
Package management has been moved into addons_contrib so the addon
can be enabled when enabling extension repositories.
This means users can test extension repositories without having to
install a separate add-on.
Additional work is still needed with the server before this is ready
for general testing though.
Part of #117286.
Add-ons using the extension API now follow changes to their
repositories.
- Removing a repository disables and removes associated add-ons.
- Disabling a repository disables the add-on but keeps add-on &
its preferences.
- Enabling a repository re-enables add-ons that use it.
- Renaming a repository updates the names of associated add-ons &
it's preferences.
Disabling all add-ons on exit could raise exceptions when `sys.modules`
contained modules that ran logic in their `__getattr__` function.
Resolve by accessing the modules name-space directly,
bypassing the `__getattr__` function.
Listing the "Blender Foundation" as copyright holder implied the Blender
Foundation holds copyright to files which may include work from many
developers.
While keeping copyright on headers makes sense for isolated libraries,
Blender's own code may be refactored or moved between files in a way
that makes the per file copyright holders less meaningful.
Copyright references to the "Blender Foundation" have been replaced with
"Blender Authors", with the exception of `./extern/` since these this
contains libraries which are more isolated, any changed to license
headers there can be handled on a case-by-case basis.
Some directories in `./intern/` have also been excluded:
- `./intern/cycles/` it's own `AUTHORS` file is planned.
- `./intern/opensubdiv/`.
An "AUTHORS" file has been added, using the chromium projects authors
file as a template.
Design task: #110784
Ref !110783.