IFamilyLoadOptions / CPython3 Issue

I’m currently working on a python script that will batch load families . It works as is in IronPython ; however, when I switch to CPython I get a TypeError : interface takes exactly one argument line 58 (the famDoc.LoadFamily(doc,FamilyOption()) line). It appears to be related to the FamilyOption Class, but can’t seem to figure out how to fix it. Any thoughts?

class FamilyOption(IFamilyLoadOptions):
    def OnFamilyFound(self, familyInUse, overwriteParameterValues):
        overwriteParameterValues = True
        return True

    def OnSharedFamilyFound(self, sharedFamily, familyInUse, source, overwriteParameterValues):
        overwriteParameterValues = True
        return True

def ChangeCategory(doc, element, bic):
    # Retrieve the family from the given element
    family = element.Symbol.Family
    TransactionManager.Instance.ForceCloseTransaction()
    famDoc = doc.EditFamily(family)
    ownerFamily = famDoc.OwnerFamily
    
    # Change the category of the owner family to a new category, in this case, Windows
    ownerFamily.FamilyCategory = Category.GetCategory(famDoc, bic)
    
    # Define new subcategories to be added to the family
    newSubCats = ["Glass", "Trim", "Frame/Mullion", "Sill/Head", "Panel"]

    TransactionManager.Instance.EnsureInTransaction(famDoc)

    subCats = ownerFamily.FamilyCategory.SubCategories
    subCatDict = {}
    for s in subCats:
        subCatDict[s.Name] = s

    for w in newSubCats:
        # Add new subcategory if it does not already exist
        if w not in subCatDict:
            try:
                newCat = famDoc.Settings.Categories.NewSubcategory(ownerFamily.FamilyCategory, w)
            except: pass

    TransactionManager.Instance.TransactionTaskDone()
    
    # Start a new transaction in the main document to load the modified family
    TransactionManager.Instance.EnsureInTransaction(doc)
      
    famDoc.LoadFamily(doc, FamilyOption())
    
    TransactionManager.Instance.TransactionTaskDone()

    return ownerFamily
1 Like

Hi, and welcome,

That should help you get there

1 Like

Thanks for the reply. I’ll dig into that reference link and see what I can uncover…thanks again.

1 Like

I have the same problem as @criddell on Revit 2024.3 and default CPython3 engine.

On the last line of the following code:

# based on: https://forums.autodesk.com/t5/revit-api-forum/ifamilyloadoptions-not-respected-in-python/m-p/10683160/highlight/true#M58985
class FamilyLoaderOptionsHandler(DB.IFamilyLoadOptions):

	def OnFamilyFound(self, familyInUse, overwriteParameterValues):
		overwriteParameterValues.Value = True
		return True
	
	def OnSharedFamilyFound(self, sharedFamily, familyInUse, source, overwriteParameterValues):
		source.Value = DB.FamilySource.Family
		overwriteParameterValues.Value = True
		return True

familyLoaderOpts = FamilyLoaderOptionsHandler()

an error is raised:

interface takes exactly one argument

I tried the solution provided by @Jean-Marc but it didn’t work. I guess because the solution is for Revit 2017, and thus for IronPython2.

Does anyone know how to instantiate the class on Revit 2024/2025 with CPython3 engine?
Is this some kind of bug with PythonNET 2.5 class inheritance?

I would be grateful for any kind of help. Thank you in advance.

dunno.
I looked at it a bit, but I am hitting other issues related to the partial implementation of Cpython.
my advice, stay away of cpython engine in pyRevit for now. It needs some love.

1 Like

This is a known limitation of CP3 being unable to support interfaces in the revit API. General advice on dynamo forums is to use ironpython or pythonnet engines.

2 Likes

Hi @Jean-Marc ,
Thank you very much for the reply and advice.

Hi @GavinCrump ,
Thank you as well for your reply and experience.
As per latest Dynamo release notes, CP3 is actually pythonnet version 2.5:

The article recommends using pythonnet version 3.0, via package manager. Sadly I can’t install it on my Revit 2024.

1 Like

Yes generally if using dynamo you’ll be limited to the builds autodesk chooses to update, which these days is only the latest one. If you need to span python in revit 2024 or prior ironpython is the only option in my experience, security risks and all. If you jump to c# this of course fixes these issues but requires more work/learning.

1 Like

Hi @GavinCrump
Thank you very much for your useful experience.

1 Like

Try this:

from pyrevit import EXEC_PARAMS
class FamilyLoaderOptionsHandler(DB.IFamilyLoadOptions):
	__namespace__ = EXEC_PARAMS.exec_id
	def OnFamilyFound(self, familyInUse, overwriteParameterValues):
		overwriteParameterValues.Value = True
		return True
	
	def OnSharedFamilyFound(self, sharedFamily, familyInUse, source, overwriteParameterValues):
		source.Value = DB.FamilySource.Family
		overwriteParameterValues.Value = True
		return True
2 Likes

FYI: the CPython engine in pyrevit 5 is python.net 3 :wink:

3 Likes