feat: populate AppDomain session environment dictionary#3122
feat: populate AppDomain session environment dictionary#3122
Conversation
The C# loader never seeded the PYREVITEnvVarsDict AppDomain key, so all pyrevit.sessioninfo / telemetry / logger APIs in scripts were crashing with NullReferenceException when EnvDictionary() tried to cast null to PythonDictionary. Changes: - EnvVariables.cs (Runtime): add static EnvDictionary.Seed() that accepts a plain Dictionary<string, object>, creates/gets the PythonDictionary internally, populates it, and stores it in AppDomain. Keeping PythonDictionary creation inside the Runtime avoids a compile-time IronPython reference in the loader (UseIronPython=false). - PyRevitConfig.cs: add 12 missing config properties read from the same INI sections as PyRevitConsts in the CLI library: LoggingLevel (verbose/debug → 0/1/2), FileLogging, AutoUpdate, OutputStyleSheet [core]; TelemetryState, TelemetryUTCTimeStamps, TelemetryFilePath, TelemetryServerUrl, TelemetryIncludeHooks, AppTelemetryState, AppTelemetryServerUrl, AppTelemetryEventFlags [telemetry]. - EnvDictionarySeeder.cs (new): builds the values dict from PyRevitConfig and UIApplication, resolves pyRevit version from the version file and IronPython version from the engine DLL, then calls EnvDictionary.Seed() via reflection (same pattern as ScriptExecutor.Initialize/ExecuteScript). - SessionManagerService.cs: call SeedEnvironmentDictionary() immediately after InitializeScriptExecutor() (which loads _runtimeAssembly) and before any extension startup script runs. Failure is logged as a warning rather than thrown to preserve graceful degradation. - ScriptMetadataParsingTest.cs: add TestLoggingLevelConfigFromIni, TestTelemetryConfigFromIni, TestFileLoggingAndAutoUpdateConfigFromIni. https://claude.ai/code/session_013HpJtXCz4WQuSaNxY2gSxK
There was a problem hiding this comment.
Pull request overview
This PR fixes a startup/runtime crash path by ensuring the Runtime’s AppDomain environment dictionary (PYREVITEnvVarsDict) is seeded by the C# loader before any extension startup scripts run, and extends the loader-side PyRevitConfig to expose additional core/telemetry settings (with new unit tests validating the parsing).
Changes:
- Add
EnvDictionary.Seed(Dictionary<string, object>)in the Runtime to create/populate thePythonDictionaryin AppDomain (loader calls via reflection). - Add new config properties in
PyRevitConfigfor logging, file logging, auto-update, output stylesheet, and telemetry/app-telemetry settings. - Seed the environment dictionary during session load and add unit tests covering the new config parsing.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| dev/pyRevitLabs.PyRevit.Runtime/EnvVariables.cs | Adds EnvDictionary.Seed(...) to create/populate the AppDomain PythonDictionary. |
| dev/pyRevitLoader/pyRevitAssemblyBuilder/SessionManager/EnvDictionarySeeder.cs | New loader helper that builds a CLR dictionary of session/config values and invokes the Runtime seeding method via reflection. |
| dev/pyRevitLoader/pyRevitAssemblyBuilder/UIManager/SessionManagerService.cs | Calls environment seeding after script executor init and before running any extension startup scripts. |
| dev/pyRevitLoader/pyRevitExtensionParser/PyRevitConfig.cs | Adds missing core + telemetry config properties read from the INI file. |
| dev/pyRevitLoader/pyRevitExtensionParserTester/ScriptMetadataParsingTest.cs | Adds unit tests for the new config properties and round-trip writes. |
dev/pyRevitLoader/pyRevitExtensionParserTester/ScriptMetadataParsingTest.cs
Outdated
Show resolved
Hide resolved
dev/pyRevitLoader/pyRevitAssemblyBuilder/SessionManager/EnvDictionarySeeder.cs
Outdated
Show resolved
Hide resolved
dev/pyRevitLoader/pyRevitAssemblyBuilder/SessionManager/EnvDictionarySeeder.cs
Show resolved
Hide resolved
dev/pyRevitLoader/pyRevitAssemblyBuilder/UIManager/SessionManagerService.cs
Outdated
Show resolved
Hide resolved
…gerService.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…arsingTest.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…tionarySeeder.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@OnePowerUser88 |
Can you accept the invite to the pyrevitDev team so that I can assign you reviews more directly? @OnePowerUser88 |
|
Note to self and others: |
Updated the assignment of the telemetry file path in EnvDictionarySeeder.cs to directly use the config value instead of an empty string. This change ensures that the telemetry file path is correctly populated from the configuration.
…rsingTest.cs. This cleanup enhances test clarity and focuses on essential configuration validations.
Done, thanks! Did not get a notification for this, but found it under "Organizations". Might take a couple of says before I have spare time to review anything, but will update when I do. |
dev/pyRevitLoader/pyRevitAssemblyBuilder/SessionManager/EnvDictionarySeeder.cs
Show resolved
Hide resolved
Updated the order of command flags in the pyrevit-autocomplete.go file to ensure consistent flag placement across commands. This change improves readability and maintainability of the code.
Introduced a new constant for the telemetry directory in EnvDictionarySeeder.cs, updating the telemetry file path assignment to use this new key. This change enhances the configuration management for telemetry data.
Enhanced the documentation for the LoggingLevel property to clarify that it is read-only and can be modified by setting the [core] verbose or debug INI keys. This improves the understanding of configuration options for users.
…ocomplete.go Updated multiple binary files and resolved merge conflicts in the pyrevit-autocomplete.go file. This includes reordering command flags for consistency and improving code clarity. These changes enhance the overall stability and maintainability of the project.
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26061+1357-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26061+1403-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26069+2130-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26071+0706-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26073+1714-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26073+2220-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26074+1648-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26076+0001-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26077+2319-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26079+2333-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26080+1314-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2031-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2042-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2045-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2048-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2106-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26083+2130-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26086+2004-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26088+1318-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26089+1231-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+0549-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+1533-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+1536-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+1540-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+1540-wip |
|
📦 New work-in-progress (wip) builds are available for 6.1.0.26090+1556-wip |
|
📦 New public release are available for 6.2.0.26090+1754 |
The C# loader never seeded the PYREVITEnvVarsDict AppDomain key, so all pyrevit.sessioninfo / telemetry / logger APIs in scripts were crashing with NullReferenceException when EnvDictionary() tried to cast null to PythonDictionary.
Changes:
EnvVariables.cs (Runtime): add static EnvDictionary.Seed() that accepts a plain Dictionary<string, object>, creates/gets the PythonDictionary internally, populates it, and stores it in AppDomain. Keeping PythonDictionary creation inside the Runtime avoids a compile-time IronPython reference in the loader (UseIronPython=false).
PyRevitConfig.cs: add 12 missing config properties read from the same INI sections as PyRevitConsts in the CLI library: LoggingLevel (verbose/debug → 0/1/2), FileLogging, AutoUpdate, OutputStyleSheet [core]; TelemetryState, TelemetryUTCTimeStamps, TelemetryFilePath, TelemetryServerUrl, TelemetryIncludeHooks, AppTelemetryState, AppTelemetryServerUrl, AppTelemetryEventFlags [telemetry].
EnvDictionarySeeder.cs (new): builds the values dict from PyRevitConfig and UIApplication, resolves pyRevit version from the version file and IronPython version from the engine DLL, then calls EnvDictionary.Seed() via reflection (same pattern as ScriptExecutor.Initialize/ExecuteScript).
SessionManagerService.cs: call SeedEnvironmentDictionary() immediately after InitializeScriptExecutor() (which loads _runtimeAssembly) and before any extension startup script runs. Failure is logged as a warning rather than thrown to preserve graceful degradation.
ScriptMetadataParsingTest.cs: add TestLoggingLevelConfigFromIni, TestTelemetryConfigFromIni, TestFileLoggingAndAutoUpdateConfigFromIni.
https://claude.ai/code/session_013HpJtXCz4WQuSaNxY2gSxK
Unit tests (no Revit needed)
Build
pipenv run pyrevit build products DebugSmoke test in Revit — run this in any script: