# Python Ecosystems for Revit **Comprehensive analysis of all Python runtime options available for Revit development.** This document provides an objective comparison of Python runtimes, their strengths, weaknesses, and technical characteristics. Choose based on your specific needs and constraints. --- ## Available Python Runtimes | Runtime | Source | Python Version | Integration | Status | | ------------------------ | ----------------------------------- | -------------- | ----------- | ---------------------------- | | **IronPython 2.7** | pyRevit (default), Dynamo (package) | 2.7 | Direct CLR | Legacy, unmaintained | | **IronPython 3.4** | pyRevit (option), Dynamo (package) | 3.4 | Direct CLR | Active but weak | | **CPython 3.12** | pyRevit (experimental) | 3.12 | PythonNet | Experimental, unstable | | **CPython 3.9** | Dynamo (default, 2022+) | 3.9 | PythonNet | Active, pre-shipped packages | | **CPython 3.11** | Dynamo (package, 2025+) | 3.11 | PythonNet3 | Active, solves .NET issues | | **CPython 3.13** | RevitDevTool | 3.13 | PythonNet3 | Active, auto-dependencies | --- ## The Fragmentation Problem Revit Python development is fragmented due to: 1. **Legacy IronPython dominance** - IronPython 2.7 still default in many tools despite being obsolete 2. **CPython integration challenges** - .NET interface and extension method limitations with PythonNet 3. **Different tool philosophies** - Visual programming (Dynamo) vs code-first (pyRevit, RevitDevTool) 4. **Dependency management gaps** - Most tools lack automatic dependency resolution 5. **Debugging limitations** - Limited IDE integration across most options Each option represents different trade-offs between .NET integration, ecosystem access, and tooling support. --- ## IronPython 2.7 (Legacy) **Status:** No longer maintained, obsolete ### Technical Characteristics ``` IronPython 2.7 ├─ Python 2.7 runtime (EOL 2020) ├─ Direct CLR/.NET binding ├─ No PythonNet layer └─ Built into pyRevit, available in Dynamo ``` ### Strengths - ✅ **Direct .NET integration** - No marshaling, can implement interfaces directly - ✅ **Zero setup** - Built into pyRevit - ✅ **Stable** - No breaking changes (frozen) - ✅ **Extension methods work** - Direct CLR access ### Weaknesses - ❌ **Python 2.7 obsolete** - End-of-life since 2020 - ❌ **No maintenance** - Security and bug fixes stopped - ❌ **No modern syntax** - No f-strings, type hints, async/await, walrus operator - ❌ **No modern packages** - pandas, numpy, scikit-learn incompatible - ❌ **No dependency management** - Manual package handling ### Use Cases - Maintaining legacy pyRevit scripts - Simple Revit API automation (no external packages) - When modernization would break compatibility --- ## IronPython 3.4 (Active but Weak) **Status:** Maintained but slow development ### Technical Characteristics ``` IronPython 3.4 ├─ Python 3.4+ runtime ├─ Direct CLR/.NET binding ├─ Slow development pace └─ Available in pyRevit and Dynamo ``` ### Strengths - ✅ **Python 3 syntax** - f-strings, type hints available - ✅ **Direct .NET integration** - Can implement interfaces - ✅ **Extension methods work** - Direct CLR access ### Weaknesses - ❌ **NOT CPython** - Incompatible with CPython ecosystem - ❌ **No modern packages** - pandas, numpy still unavailable - ❌ **Slow development** - Not many updates - ❌ **Small community** - Limited support - ❌ **Dead-end technology** - IronPython has limited future ### Use Cases - Upgrading from IronPython 2.7 (syntax only) - Need .NET interface implementation without CPython - Cannot use CPython for some reason --- ## CPython 3.12 (pyRevit Experimental) **Status:** Experimental, not production-ready ### Technical Characteristics ``` pyRevit + CPython 3.12 ├─ CPython 3.12 runtime ├─ PythonNet for .NET integration ├─ Reload engine broken └─ Manual dependency management ``` ### Strengths - ✅ **Modern Python** - Latest syntax and features - ✅ **Full ecosystem** - Can use pandas, numpy, etc. ### Weaknesses - ❌ **Reload engine broken** - Module cache not cleared between runs - ❌ **State pollution** - Previous execution affects next run - ❌ **Manual dependencies** - pip install required - ❌ **Experimental** - Unstable for production use - ❌ **No debugger integration** - Limited debugging tools ### Use Cases - Experimentation and testing only - Consider stability requirements for production --- ## CPython 3.9 (Dynamo Default, 2022+) **Status:** Active, default in Dynamo ### Technical Characteristics ``` Dynamo + CPython 3.9 ├─ CPython 3.9 runtime ├─ PythonNet for .NET integration ├─ Pre-shipped: pandas, numpy, matplotlib, scipy, openpyxl └─ Visual programming + Python hybrid ``` ### Strengths - ✅ **Modern Python 3.9** - Full modern syntax - ✅ **Pre-shipped packages** - pandas, numpy, matplotlib, scipy, openpyxl included - ✅ **Visual + code hybrid** - Graph + Python nodes - ✅ **Built-in Revit integration** - Part of Dynamo ### Weaknesses - ❌ **Cannot implement .NET interfaces** - PythonNet limitation (no `__namespace__` workaround available) - ❌ **Extension methods fail** - LINQ methods like `.Where()`, `.Select()` don't work - ❌ **Manual dependency management** - venv setup for additional packages - ❌ **No debugger integration** - Limited debugging tools ### Technical Limitations ```python # Dynamo CPython 3.9 limitations from Autodesk.Revit.UI import IExternalEventHandler from System.Linq import Enumerable # ❌ Cannot implement .NET interfaces class MyHandler(IExternalEventHandler): # Fails! def Execute(self, app): pass # ❌ LINQ extension methods don't work walls = Enumerable.Where(collector, lambda x: x.Name.Contains("Wall")) # Fails! ``` ### Use Cases - Visual programming preference - Using pre-shipped packages (pandas, numpy) - Don't need .NET interface implementation - Accepting extension method limitations --- ## CPython 3.11 + PythonNet3 (Dynamo 2025+) **Status:** Active, solves .NET integration issues ### Technical Characteristics ``` Dynamo + PythonNet3 + CPython 3.11 ├─ CPython 3.11 runtime ├─ PythonNet3 for enhanced .NET integration ├─ Solves interface and extension method issues └─ Available via Dynamo package (Revit 2025+) ``` ### Strengths - ✅ **Modern Python 3.11** - Latest features - ✅ **LINQ extension methods work** - Full LINQ support (.Where(), .Select(), etc.) - ✅ **Methods with out/ref parameters** - Can implement/override methods with out/ref - ✅ **Overloaded operators** - Can use C# operator overloading (e.g., XYZ addition) - ✅ **Pre-shipped packages** - pandas, numpy, etc. included - ✅ **Visual + code hybrid** - Dynamo graph + Python ### Weaknesses - ⚠️ **Requires Revit 2025+** - Not available for older versions - ⚠️ **Package installation required** - Not default, must install package - ❌ **Manual dependency management** - Additional packages need manual setup - ❌ **No debugger integration** - Limited debugging tools ### Technical Capabilities ```python # Dynamo PythonNet3 3.11 from Autodesk.Revit.DB import * from System.Linq import Enumerable import System # ✅ LINQ extension methods work clr.ImportExtensions(System.Linq) walls = FilteredElementCollector(doc).OfClass(FamilyInstance)\ .Where(System.Func[Element, bool](lambda e: "Tree" in e.Name))\ .Select[Element, str](System.Func[Element, str](lambda e: e.Name)) # ✅ Methods with out/ref parameters work class MyFamilyLoadOptions(IFamilyLoadOptions): def OnFamilyFound(self, familyInUse, _overwriteParameterValues): overwriteParameterValues = True return (True, overwriteParameterValues) # Return tuple for out params # ✅ Overloaded operators work point = XYZ(10, 10, 0) + XYZ(1, 1, 1) # Operator overloading works ``` **Learn more:** [PythonNet3: A New Python to Fix Everything](https://dynamobim.org/pythonnet3-a-new-dynamo-python-to-fix-everything/#extension-methods) ### Use Cases - Revit 2025+ projects - Need LINQ extension methods or out/ref parameter support - Visual programming preference - Willing to install Dynamo package --- ## CPython 3.13 + PythonNet3 (RevitDevTool) **Status:** Active, focus on automatic dependency management ### Technical Characteristics ``` RevitDevTool + PythonNet3 + CPython 3.13 ├─ Latest Python 3.13 ├─ PythonNet3 for .NET integration ├─ UV resolver for automatic dependencies ├─ Per-script module isolation └─ VSCode debugger integration (debugpy) ``` ### Strengths - ✅ **Latest Python 3.13** - Newest features and performance - ✅ **Automatic dependency resolution** - PEP 723 + UV solver - No manual pip install - Conflict detection and resolution - Per-script dependency declarations - ✅ **VSCode debugger integration** - Full IDE debugging - Breakpoints and conditional breakpoints - Step through code (F10, F11) - Variable inspection - Debug console - ✅ **Clean module reload** - Per-script isolation - ✅ **Zero setup** - No venv or infrastructure needed ### Weaknesses - ❌ **Same .NET limitations as Dynamo CPython 3.9** - Cannot implement .NET interfaces directly (workaround: `__namespace__` with overhead) - LINQ extension methods don't work - PythonNet limitation, not tool-specific - ⚠️ **Dependencies NOT pre-shipped** - Resolved on-demand (requires internet on first run) - Different from Dynamo approach ### Technical Limitations & Workarounds ```python # RevitDevTool PythonNet3 limitations (same as Dynamo 3.9) from Autodesk.Revit.UI.Selection import ISelectionFilter from System import Guid from System.Linq import Enumerable # ❌ Cannot implement .NET interfaces directly class MyFilter(ISelectionFilter): # Fails! def AllowElement(self, element): return True # ✅ Workaround: Use __namespace__ (adds runtime overhead) class MyFilter(ISelectionFilter): __namespace__ = str(Guid.NewGuid()) # Must be unique per execution def AllowElement(self, element): return True # Works but with overhead # ❌ LINQ extension methods don't work walls = Enumerable.Where(collector, lambda x: x.Name.Contains("Wall")) # Fails! ``` **Note:** The `__namespace__` workaround allows interface implementation but adds runtime overhead for dynamic type checking. See `RevitDevTool.PythonDemo/commands/selectionfilter_script.py` for example. ### Automatic Dependency Example ```python # /// script # dependencies = [ # "pandas==2.1.0", # "numpy>=1.24", # "scikit-learn==1.3.0" # ] # /// import pandas as pd import numpy as np from sklearn.ensemble import RandomForestClassifier # Dependencies auto-installed by UV resolver # No manual setup required ``` ### Use Cases - Developer workflows requiring debugging - Data science and research projects - Computational design - AI/ML integration with Revit - Rapid prototyping with automatic dependencies - Accepting .NET interface/extension limitations --- ## Comprehensive Comparison | Feature | IP 2.7 | IP 3.4 | pyRevit CP | Dynamo CP 3.9 | Dynamo PNet3 | RevitDevTool | | ------------------------------ | ---------- | ---------- | ------------ | ------------- | ------------ | ------------ | | **Python Version** | 2.7 | 3.4 | 3.12 | 3.9 | 3.11 | 3.13 | | **Runtime** | IronPython | IronPython | CPython | CPython | CPython | CPython | | **Status** | Legacy | Weak | Experimental | Active | Active | Active | | **Modern Syntax** | ❌ | ⚠️ | ✅ | ✅ | ✅ | ✅ | | **pandas/numpy** | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | | **Pre-shipped packages** | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | | **LINQ Extensions** | ✅ | ✅ | ⚠️ | ❌ | ✅ | ❌ | | **out/ref parameters** | ✅ | ✅ | ⚠️ | ❌ | ✅ | ❌ | | **Auto-dependencies** | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | **VSCode Debugger** | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | **Module Isolation** | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | | **Reload Works** | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | | **Setup Required** | None | None | Manual | Manual | Manual | None | ### Key Trade-offs **Direct .NET Integration vs Modern Python:** - IronPython: Full .NET access, obsolete Python - CPython: Modern Python, limited .NET access **Pre-shipped vs On-demand Packages:** - Dynamo: Packages included, larger install - RevitDevTool: Packages resolved on-demand, smaller footprint **Visual vs Code-first:** - Dynamo: Visual programming with Python nodes - pyRevit/RevitDevTool: Code-centric execution **Debugging Capabilities:** - Most tools: Print debugging or pdb - RevitDevTool: Full VSCode IDE integration --- ### Dependency Management Approaches **Manual (Most tools):** ```bash # User must run manually pip install pandas numpy scikit-learn ``` **Pre-shipped (Dynamo):** ```python # Already available import pandas as pd import numpy as np # No installation needed ``` **Automatic (RevitDevTool):** ```python # /// script # dependencies = ["pandas==2.1.0"] # /// import pandas as pd # Auto-installed on first run ``` --- ## Ecosystem Analysis ### Current Landscape The Revit Python ecosystem is fragmented across multiple incompatible approaches: **Legacy Era (IronPython 2.7):** - Direct .NET access - No modern packages - Still default in many tools **Transition Era (IronPython 3.4):** - Attempt to modernize syntax - Still incompatible with CPython ecosystem - Limited adoption **Modern Era (CPython):** - Full ecosystem access - .NET integration challenges - Multiple competing solutions ### Strengths of Current Ecosystem - ✅ **Multiple options** - Different tools for different needs - ✅ **Mature tools** - pyRevit and Dynamo well-established - ✅ **Large communities** - Extensive support and resources - ✅ **Proven workflows** - Battle-tested in production ### Weaknesses of Current Ecosystem - ❌ **Fragmentation** - No unified approach - ❌ **Compatibility issues** - Scripts not portable between tools - ❌ **Learning curve** - Must learn multiple tools - ❌ **Debugging gaps** - Limited IDE integration - ❌ **Dependency chaos** - Manual management in most tools --- ## Choosing a Runtime Consider these factors when selecting a Python runtime: ### Project Requirements - **Need LINQ extension methods?** → IronPython or Dynamo PythonNet3 (2025+) - **Need out/ref parameters?** → IronPython or Dynamo PythonNet3 (2025+) - **Need modern packages?** → Any CPython option - **Need visual programming?** → Dynamo - **Need IDE debugging?** → RevitDevTool - **Need pre-shipped packages?** → Dynamo ### Team Constraints - **Legacy codebase?** → Stay with current runtime - **Team expertise?** → Match team's Python knowledge - **Revit version?** → Check compatibility - **Internet access?** → Consider pre-shipped vs on-demand ### Development Workflow - **Rapid prototyping?** → Auto-dependencies helpful - **Production deployment?** → Stability matters - **Research/experimentation?** → Debugging tools valuable - **End-user tools?** → Visual programming may help --- ## See Also - [vs pyRevit](CodeExecute-VsPyRevit.md) - Detailed pyRevit comparison - [Python Execution](CodeExecute-PythonExecution.md) - How Python execution works - [Python Debugging](CodeExecute-PythonDebugging.md) - VSCode debugger guide - [.NET Execution](CodeExecute-DotNetExecution.md) - C# assembly execution