-
Notifications
You must be signed in to change notification settings - Fork 0
CodeExecute PythonEcosystems
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.
| 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 |
Revit Python development is fragmented due to:
- Legacy IronPython dominance - IronPython 2.7 still default in many tools despite being obsolete
- CPython integration challenges - .NET interface and extension method limitations with PythonNet
- Different tool philosophies - Visual programming (Dynamo) vs code-first (pyRevit, RevitDevTool)
- Dependency management gaps - Most tools lack automatic dependency resolution
- Debugging limitations - Limited IDE integration across most options
Each option represents different trade-offs between .NET integration, ecosystem access, and tooling support.
Status: No longer maintained, obsolete
IronPython 2.7
ββ Python 2.7 runtime (EOL 2020)
ββ Direct CLR/.NET binding
ββ No PythonNet layer
ββ Built into pyRevit, available in Dynamo
- β 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
- β 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
- Maintaining legacy pyRevit scripts
- Simple Revit API automation (no external packages)
- When modernization would break compatibility
Status: Maintained but slow development
IronPython 3.4
ββ Python 3.4+ runtime
ββ Direct CLR/.NET binding
ββ Slow development pace
ββ Available in pyRevit and Dynamo
- β Python 3 syntax - f-strings, type hints available
- β Direct .NET integration - Can implement interfaces
- β Extension methods work - Direct CLR access
- β 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
- Upgrading from IronPython 2.7 (syntax only)
- Need .NET interface implementation without CPython
- Cannot use CPython for some reason
Status: Experimental, not production-ready
pyRevit + CPython 3.12
ββ CPython 3.12 runtime
ββ PythonNet for .NET integration
ββ Reload engine broken
ββ Manual dependency management
- β Modern Python - Latest syntax and features
- β Full ecosystem - Can use pandas, numpy, etc.
- β 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
- Experimentation and testing only
- Consider stability requirements for production
Status: Active, default in Dynamo
Dynamo + CPython 3.9
ββ CPython 3.9 runtime
ββ PythonNet for .NET integration
ββ Pre-shipped: pandas, numpy, matplotlib, scipy, openpyxl
ββ Visual programming + Python hybrid
- β 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
- β 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
# 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!- Visual programming preference
- Using pre-shipped packages (pandas, numpy)
- Don't need .NET interface implementation
- Accepting extension method limitations
Status: Active, solves .NET integration issues
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+)
- β 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
β οΈ 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
# 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 worksLearn more: PythonNet3: A New Python to Fix Everything
- Revit 2025+ projects
- Need LINQ extension methods or out/ref parameter support
- Visual programming preference
- Willing to install Dynamo package
Status: Active, focus on automatic dependency management
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)
- β 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
- β 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
- Cannot implement .NET interfaces directly (workaround:
β οΈ Dependencies NOT pre-shipped- Resolved on-demand (requires internet on first run)
- Different from Dynamo approach
# 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.
# /// 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- 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
| 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 |
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
Manual (Most tools):
# User must run manually
pip install pandas numpy scikit-learnPre-shipped (Dynamo):
# Already available
import pandas as pd
import numpy as np
# No installation neededAutomatic (RevitDevTool):
# /// script
# dependencies = ["pandas==2.1.0"]
# ///
import pandas as pd
# Auto-installed on first runThe 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
- β 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
- β 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
Consider these factors when selecting a Python runtime:
- 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
- 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
- Rapid prototyping? β Auto-dependencies helpful
- Production deployment? β Stability matters
- Research/experimentation? β Debugging tools valuable
- End-user tools? β Visual programming may help
- vs pyRevit - Detailed pyRevit comparison
- Python Execution - How Python execution works
- Python Debugging - VSCode debugger guide
- .NET Execution - C# assembly execution