Skip to content

refactor: Rewrite pyRevit configurations - #2482

Draft
dosymep wants to merge 54 commits into
developfrom
features/configuration
Draft

refactor: Rewrite pyRevit configurations#2482
dosymep wants to merge 54 commits into
developfrom
features/configuration

Conversation

@dosymep

@dosymep dosymep commented Dec 18, 2024

Copy link
Copy Markdown
Member
  • added config abstraction
  • added config overrides (need testing and design the logic of work)
  • replace ini lib to ini-parser
  • added json configuration
  • added yaml configuration (doesn't work I need to figure out the parser library)

I think in general a start has been made, it remains to rewrite the logic of the config in python

@dosymep dosymep added Bug Enhancement Enhancement request [class->Improved #{number}: {title}] Backward Compatibility Backward Compatibility Issue with Older Revit Versions DotNet API Issues related to pyRevitLabs libraries [subsystem] API Change Revit API change that breaks pyRevit [class->Upgraded #{number}: {title}] labels Dec 18, 2024
@dosymep dosymep added this to the post pyRevit 5 RC milestone Dec 18, 2024
@dosymep dosymep linked an issue Dec 18, 2024 that may be closed by this pull request
5 tasks
@dosymep
dosymep marked this pull request as ready for review December 18, 2024 11:21
@dosymep dosymep assigned dosymep and unassigned sanzoghenzo Dec 18, 2024
@dosymep
dosymep marked this pull request as draft December 18, 2024 11:23
@dosymep

dosymep commented Dec 18, 2024

Copy link
Copy Markdown
Member Author

@jmcouffin @sanzoghenzo how to trigger github action?

@jmcouffin

Copy link
Copy Markdown
Contributor

@jmcouffin @sanzoghenzo how to trigger github action?

image

@jmcouffin

Copy link
Copy Markdown
Contributor

I just launched it.
15min+ to go

I won't be able to review just now, best I can do is install the wip that will be created

@sanzoghenzo sanzoghenzo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome job @dosymep !

I didn't run the code, only skimmed through, and only found some grammar to fix (ShouldThrows -> ShouldThrow).

Do you think it would be worth creating separate repo(s) and nuget package(s) for this feature (just to start the transition to a better code structure)?

Comment thread dev/pyRevitLabs/tests/pyRevitLabs.Configurations.Tests/ConfigurationTests.cs Outdated
Comment thread dev/pyRevitLabs/tests/pyRevitLabs.Configurations.Tests/ConfigurationTests.cs Outdated
Comment thread dev/pyRevitLabs/pyRevitLabs.PyRevit/PyRevitConfigs.cs Outdated
@dosymep

dosymep commented Dec 20, 2024

Copy link
Copy Markdown
Member Author

creating separate repo(s) and nuget package(s)

it won't work, we have dependencies on this repo, at the moment I still don't know how to do this :(

@jmcouffin jmcouffin changed the title Rewrite pyRevit configurations refactor: Rewrite pyRevit configurations Feb 1, 2025
# Conflicts:
#	bin/netcore/pyRevitLabs.Emojis.dll
#	bin/netfx/pyRevitLabs.Emojis.dll
#	dev/pyRevitLabs/pyRevitLabs.PyRevit/PyRevitClones.cs
#	dev/pyRevitLabs/pyRevitLabs.PyRevit/PyRevitConfig.cs
#	dev/pyRevitLabs/pyRevitLabs.PyRevit/PyRevitConfigs.cs
#	pyrevitlib/pyrevit/coreutils/configparser.py
@jmcouffin

Copy link
Copy Markdown
Contributor

Should we keep this one opened? @dosymep

@dosymep

dosymep commented Jan 12, 2026

Copy link
Copy Markdown
Member Author

Should we keep this one opened? @dosymep

Let it be, maybe I'll continue someday, or someone else will

@jmcouffin jmcouffin removed Bug DotNet API Issues related to pyRevitLabs libraries [subsystem] API Change Revit API change that breaks pyRevit [class->Upgraded #{number}: {title}] labels Feb 21, 2026
@jmcouffin

Copy link
Copy Markdown
Contributor

@OnePowerUser88 ☝️

@OnePowerUser88

Copy link
Copy Markdown
Contributor

I've been testing the branch locally with Revit 2026 (build + smoke test, then fixing runtime issues so it runs). Here's a short summary and the list of changes I have made on top of the branch to get everything working. Sharing for discussion, as I'm not shure how to contribute to a PR on GH, but can contribute my code if someone can give me guidance (I assume I can make a PR to the feature/configuration branch?).

Summary

The new C# config stack (typed sections, INI provider, GetValueOrDefault / SaveSection) is in place and the INI file is read/written correctly. Python uses the C# layer; no revert to the old Python-only config. I only fixed bugs and added a small compatibility layer so existing code and extensions that still call user_config.core.get_option() keep working.

List of what I fixed locally (for testing)

1. pyrevitlib/pyrevit/coreutils/configparser.py

  • get_option: Use GetValueOrDefault(section, option, "") then json.loads(value); handle empty.
  • setattr: Skip __section_name and __configuration (use object.__setattr__ for those) so __init__ can set them and the rest goes through set_option.
  • Subsections: Use __configuration / __section_name; add_subsection / get_subsection return correct types and None when not found.

2. pyrevitlib/pyrevit/userconfig.py

  • Use getattr(EXEC_PARAMS, 'doc_mode', False) where doc_mode is read (not present on this branch).
  • User extension folders: Read from self.core.UserExtensions (and (self.core.UserExtensions or [])); write with framework.List[str](...) so C# gets a List<string>.
  • _SectionCompatWrapper: Wrapper around Core/Routes/Telemetry that exposes get_option / set_option and forwards other attributes to the C# section (so extensions and Settings UI keep working).
  • setattr on the wrapper: Forward property sets to the underlying C# section so Settings changes apply to the real section.
  • save_changes(): Call SaveSection with config_service.Core, config_service.Routes, config_service.Telemetry (not the Python wrappers) so the C# side gets the right type and the INI is updated.

3. dev/pyRevitLabs/pyRevitLabs.Configurations.Ini/IniConfiguration.cs

  • For requested type string, return the raw value (no JsonConvert.DeserializeObject), so Python can json.loads() it (handles arrays and other JSON).
  • Hex integer parsing for legacy INI (e.g. 0x0).
  • net48: Use Substring(1, valueToParse.Length - 2) instead of [1..^1].

4. dev/pyRevitLabs/pyRevitLabs.PyRevit/pyRevitLabs.PyRevit.csproj

  • DeployDependencies: Copy INIFileParser.dll to the output so the INI provider loads.

5. pyrevitlib/pyrevit/runtime/__init__.py

  • Resolve runtime assembly path: try BIN_DIR first, then BIN_DIR/engines/<EngineVersion>/ so the Runtime DLL is found when it's only under engines (e.g. after building the Runtime solution).

6. pyrevitlib/pyrevit/revit/tabs.py

  • _get_tabstyle / _get_family_tabstyle: Coerce index to int(...) (config can return string).
  • hex_to_brush: Defensive handling (string, default brush) so bad/malformed config doesn't crash.
  • _get_tab_orderrules: Treat tab_colors as list only when isinstance(raw, list).
  • _get_tab_filterrules: Treat tab_filtercolors as dict only when isinstance(tab_filtercolors, dict).

7. dev/pyRevitLabs/tests/.../ConfigurationServiceFixture.cs

  • Mock: Implement GetSectionNames() and GetSectionOptionNames(string) so the solution builds.

After these changes, Settings persist correctly to pyRevit_config.ini based on my testing (it might have before, but pulling the clean PR and building it was not working out-of-the-box for me).
I hope this testing is aligned with the intent of the PR?

Question: What other features or fixes are planned for this PR that I could help test or look into? For example:

  • Config overrides (design and testing of precedence/order)?
  • YAML configuration (parser library and integration)?
  • Remaining Python config logic to rewrite onto the C# layer?
  • JSON configuration (same level of testing/integration as INI)?
  • INI file locking / multi-process behaviour ([Bug]: pyRevit_config.ini is being used by another process #2512)?
  • Other?

@ChrisCrosley

Copy link
Copy Markdown
Contributor

Any objections to me taking a swing at bringing this up to date with develop?

@jmcouffin

Copy link
Copy Markdown
Contributor

Any objections to me taking a swing at bringing this up to date with develop?

I don't have any, @dosymep you?

a few notes though, I'd rather have a draft PR with no code changes and a clear plan that @dosymep or others can review before deeep diving. And there is a significant amount of drift between now and the start of this PR, 1 and a half year ago.

@dosymep

dosymep commented Jun 23, 2026

Copy link
Copy Markdown
Member Author

I don't mind, but maybe everything there is already very outdated

ChrisCrosley added a commit to ChrisCrosley/pyRevit-fork that referenced this pull request Aug 3, 2026
The override ported from pyrevitlabs#2482 only ever had a write half: setters took a
Revit year and wrote pyRevit_config.<year>.ini, but every getter, the
loader, and the migrator read the base config. The grammar was ambiguous
too -- `[<revit_year>]` followed an optional value positional, so
`pyrevit configs startuptimeout 2025` set the timeout instead of reading
the 2025 override.

Remove it and collapse the abstraction behind it: IConfigurationService
now serves exactly one configuration. Names, layered reads, and the
this[name] indexer give way to a single Configuration property;
PyRevitConfigStore caches one Lazy; the 35 PyRevitConfigs setters lose
their revitVersion parameter; UsagePatterns returns to its develop state.

Configurations tests 16 -> 14 and 91 -> 89, dropping the name-keying and
override-write cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backward Compatibility Backward Compatibility Issue with Older Revit Versions Enhancement Enhancement request [class->Improved #{number}: {title}]

Projects

Status: In Progress
Status: In progress

Development

Successfully merging this pull request may close these issues.

[Bug]: manage access to pyrevit-config.ini at startup

5 participants