Pyrevit: Crash upon processing large number of elements

Created on 1 Oct 2020  路  4Comments  路  Source: eirannejad/pyRevit

Describe the bug
This might be something unrelated to pyRevit, but I don't know where else to start.
Maybe I'm missing something fundamental here, but I've found that processing a large number of elements in one transaction (specifically changing ~20 grids extents on ~100 views, using rpw transaction wrapper) makes revit crash without any error log whatsoever. Even the journal file doesn't contain relevant information, it just ends. I didn't have such experience with a standalone C# addin. Since I feel I'm in the dark here I would like to ask if any of you have some suggestions about where to start looking, I feel it might be some memory handling related stuff, but since I have architectural background, and nothing fundamental in software development, I'm a bit uncertain.

Desktop (please complete the following information):

  • OS: WIN 10 x64
  • pyRevit Version v4.7.6

Additional context

the actual code part where the issue happens:

if ropt == opts[0] or ropt == opts[1]:
    if ropt == opts[0]:
        extentType = DatumExtentType.ViewSpecific
    else:
        extentType = DatumExtentType.Model
    with db.Transaction(ropt):
        with forms.ProgressBar(title='In Progress... ({value} of {max_value})') as pb:
            for index, view in enumerate(views):
                pb.update_progress(index+1, len(views))
                try:
                    for id in selection:
                        datumPlane = doc.GetElement(id)
                        if optEnd == 'Both' or optEnd == optsEnd[0]:
                            datumPlane.SetDatumExtentType(DatumEnds.End0, view, extentType)
                        if optEnd == 'Both' or optEnd == optsEnd[1]:
                            datumPlane.SetDatumExtentType(DatumEnds.End1, view, extentType)
                except ArgumentException:
                    continue
                except Exception as e:
                    logger.info('Element: {0} : {1}, view: {2}'.format(datumPlane.Name, id, view.Name), exc_info=1)
Question

All 4 comments

Try this. I removed the forms.ProgressBar to see if error is related to the active progress bar window. Also changed the try except block to wrap the transaction completely. The most important change is to use element_id instead of id since the latter is a builtin python function and should not be overwritten (I have a hunch that this is the real reason for the crash)

    try:
        with db.Transaction(ropt):
            for index, view in enumerate(views):
                for element_id in selection:
                    datumPlane = doc.GetElement(element_id)
                    if optEnd == "Both" or optEnd == optsEnd[0]:
                        datumPlane.SetDatumExtentType(
                            DatumEnds.End0, view, extentType
                        )
                    if optEnd == "Both" or optEnd == optsEnd[1]:
                        datumPlane.SetDatumExtentType(
                            DatumEnds.End1, view, extentType
                        )
    except ArgumentException:
        continue
    except Exception as e:
        logger.info(
            "Element: {0} : {1}, view: {2}".format(
                datumPlane.Name, element_id, view.Name
            ),
            exc_info=1,
        )

Thanks, I will give that a try soon!
I've had slight success before reading your reply with db.TransactionGroup() for the whole loop and seperate db.Transaction() for each view, and it succeeded in an empty project with that number of views and grids, but in an actual project it still crashed. I will give feedback once I'm able to tweak it again.

Good news, only replacing the id variable solved the crash. It seems I have to go through all my codes to fix this. :) Thanks!

Perfect. When a builtin function like id (or any other) is replaced by a custom function or a variable reference, all the references to this function inside other python modules, builtin or third-party, are going to reference the new function and crash if it doesn't work. This is both a feature and a bug. For example you can assign a new function to str and completely change the string conversion behaviour

Was this page helpful?
0 / 5 - 0 ratings