[New Feature Preview] Python 3 Support Issue Thread

Because Python doesn’t allow mixed indentation we opted to smooth that process for CPython3 specifically be ensuring spaces were the default. You can still “type” tab, but it will convert in the background.

Given that the world of Python is heavily baised towards spaces, any code copied from the internet and pasted into Python can cause issues when that source is most often spaces.

I’ll put my two cents in for tabs as well.

Spaces are an accessibility issue (ask anyone who uses a brail screen reader), and should be converted out for that reason alone. Add in extra file size (4x the digits per indent) and increased difficulty in “finding the missing space”, and tab superiority becomes clear.

5 Likes

I did some tests (only on SandBox for now) I only encountered one problem so far with COM interfaces which are not cast/recognized in the correct Interface (like PythonNet).
For having already worked with it ironPython3, I haven’t encountered problem before

Test Code

Test Code

# Charger les bibliothèques DesignScript et Standard Python
import sys
import clr
import System
clr.AddReference("System.Numerics")
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)
from System.Collections.Generic import List, IList, Dictionary
from System.IO import *
from System.Net import *
#
import logging
import traceback
import os 
import csv
import time
import random
import re

my_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
## Start create logger Object ##
logger = logging.getLogger("IronPython3Logger")
# set to  DEBUG
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(funcName)s :: %(message)s')
# create handler 
file_handler = logging.FileHandler(my_path + '\\IronPython3Logger.log', mode='w')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.disabled = False

assemblies = System.AppDomain.CurrentDomain.GetAssemblies()
assembly = [a for a in assemblies if 'DynamoCore' == a.GetName().Name][0]
versionDynamo = assembly.GetName().Version



logger.info("####### START TEST #######")
logger.debug(("engine :", sys.implementation.name))
logger.debug(("version :", sys.version))
logger.debug(("versionDynamo :", versionDynamo))
##############################################
logger.info("#### START TEST EXCEL INTERROP #### ")

try:
    clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' )
    from Microsoft.Office.Interop import Excel
    from System.Runtime.InteropServices import Marshal
    ex = Excel.ApplicationClass()
    ex.Visible = True
    ex.DisplayAlerts = False
    logger.debug(("excel application :", ex))
    workbook = ex.Workbooks.Add()
    logger.debug(("excel workbook :", workbook))
    ws = workbook.Worksheets[1]
    array_data = [[random.randint(1, 100) for i in range(4)] for j in range(10)]
    nbr_row = len(array_data)
    nbr_colum = len(array_data[0])
    xlrange  = ws.Range[ws.Cells(1, 1), ws.Cells(nbr_row, nbr_colum)]
    a = Array.CreateInstance(object, nbr_row, nbr_colum)
    for indexR, row in enumerate(array_data):
        for indexC , value in  enumerate(row):
            a[indexR,indexC] = System.Int32(value) if isinstance(value, System.Numerics.BigInteger) else value
    #copy Array in range
    xlrange.Value2 = a	

except Exception as ex :
    logger.exception(ex)
    
##############################################
logger.info("####### START TEST WINFORM #######")
try:
    clr.AddReference('System.Windows.Forms')
    clr.AddReference('System.Drawing')
    from System.Windows.Forms import Application
    
    import System.Drawing
    import System.Windows.Forms
    
    from System.Drawing import *
    from System.Windows.Forms import *
    
    class MainForm(Form):
        def __init__(self):
            self.InitializeComponent()
        
        def InitializeComponent(self):
            self.Name = "MainForm"
            self.Text = "Test ipy3"
            
    form = MainForm()
    form.ShowDialog()
    logger.debug(("form", form))
    
except Exception as ex :
    logger.exception(ex)
################################################
logger.info("####### START TEST Yield From Generator #######")
try:
    def generator(test = 10):
        rg = [x ** 2 for x in range(test)]
        yield from rg
        
    for i in generator():
        logger.debug(("i", i))
        
except Exception as ex :
    logger.exception(ex)
    
################################################
logger.info("####### START TEST ref and out parameters #######")
try:
    d = { "a":100.1, "b":200.2, "c":300.3 }
    d = Dictionary[str, float](d)
    ref_out = clr.Reference[float]()
    d.TryGetValue("b", ref_out)
    logger.debug(("ref_out.Value", ref_out.Value))
        
except Exception as ex :
    logger.exception(ex)
    
################################################
logger.info("####### START TEST F String #######")
try:
    for i in range(10):
        logger.debug(("f'{i}'", f"{i}"))
        
except Exception as ex :
    logger.exception(ex)
    
################################################
logger.info("####### START TEST .Net check Type and Conversion #######")
try:
    i = 10
    logger.debug(("i value", i, "i.GetType()", i.GetType()))
    j = i.ToString()
    logger.debug(("j value", j, "j.GetType()", j.GetType()))
    logger.info("Check Numerics.BigInteger")
    k = i ** 100
    logger.debug(("k value", k, "k.GetType()", k.GetType()))
        
except Exception as ex :
    logger.exception(ex)
    
################################################
logger.info("####### START TEST Spelling Correction via Microsoft.Office.Interop.Word #######")
docWord = None
app = None
try:
    clr.AddReference("Microsoft.Office.Interop.Word")
    import Microsoft.Office.Interop.Word as Word
    
    clr.AddReference("office")
    from Microsoft.Office.Core import *
    
    clr.AddReference("System.Runtime.InteropServices")
    import System.Runtime.InteropServices
    
    # french words
    lstWord = ["hello", "agile", "albumm", "animall", "angle"]
    out = []
    app = Word.ApplicationClass()
    docWord = app.Documents.Add()
    # automatically detects the language you are using as you type
    languageAutoCheck = app.CheckLanguage 
    # the language selected for the Microsoft Word user interface
    currentUILangInt = app.Language 
    currentUILanguage = System.Enum.ToObject(MsoLanguageID, currentUILangInt)
    
    # check words
    for w in lstWord:
        spellingIsCorrect = app.CheckSpelling(w)
        if spellingIsCorrect:
            #grammarIsCorrect = app.CheckGrammar(w)
            out.append([w, spellingIsCorrect])
        else:
            suggestions = [x.Name for x in app.GetSpellingSuggestions(w)] 
            out.append([w, spellingIsCorrect, suggestions])
    logger.debug(("result", out))
except Exception as ex :
    logger.exception(ex)
finally:
    if docWord is not None:
        docWord.Close()
    if app is not None:
        app.Quit()
        app = None
    
################################################
logger.info("####### START TEST LINQ1 #######")
try:
    clr.AddReference("System.Core")
    clr.ImportExtensions(System.Linq)
    #
    lst_int = list(range(10))
    resultSquare = lst_int.Select(lambda x : x ** 2).ToList()
    logger.debug(("resultSquare", resultSquare))
    
except Exception as ex :
    logger.exception(ex)
################################################
logger.info("####### START TEST LINQ2 #######")
try:
    clr.AddReference("System.Core")
    clr.ImportExtensions(System.Linq)
    #
    lst_points = [DS.Point.ByCoordinates(random.randint(0, 10), random.randint(0, 10), random.randint(0, 10)) for i in range(10)]
    resultPoint = lst_points.FindAll(lambda x : x.Z > 0)
    logger.debug(("resultPoint", resultPoint))
except Exception as ex :
    logger.exception(ex)
    logger.warn("Some Python List<Type> seem not converted to Net List (except basic types?)")
################################################
logger.info("####### START TEST LINQ3 #######")
try:
    #
    lst_points = List[DS.Point]([DS.Point.ByCoordinates(random.randint(0, 10), random.randint(0, 10), random.randint(0, 10)) for i in range(10)])
    resultPoint = lst_points.FindAll(lambda x : x.Z > 0)
    logger.debug(("resultPoint", resultPoint))
except Exception as ex :
    logger.exception(ex)
    
################################################
logger.info("####### START TEST LINQ4 MULTIPROCESSING #######")
elapse1 = "0 s"
elapse2 = "0 s"
try:
    #
    lst_points = List[DS.Point]([DS.Point.ByCoordinates(random.randint(0, 10), random.randint(0, 10), random.randint(0, 10)) for i in range(1000000)])
    lst_pair_points = [[lst_points[i], lst_points[i+1]] for i in range(0, len(lst_points), 2)]
    logger.debug(("lst_pair_points.Count", lst_pair_points.Count))
    #
    def drawlines(lstpt):
        outlines = []
        for idx, pt in enumerate(lstpt):
            if idx > 0 and lstpt[idx - 1].DistanceTo(pt) > 0.5:
                line = Line.ByStartPointEndPoint(lstpt[idx - 1], pt)
                outlines.append(line)
        return outlines
    #
    logger.info("test without AsParallel")
    start = time.time()
    result =[]
    for pp in lst_pair_points:
        result.append(drawlines(pp))
    elapse1 = ("%s s" % (time.time()-start))
    print(("time elapse without AsParallel", elapse1))
    time.sleep(1)
    #
    logger.info("test with AsParallel")
    start2 = time.time()
    threadResult = lst_pair_points.AsParallel().Select(lambda sublst: drawlines(sublst)).ToList()
    elapse2 = ("%s s" % (time.time()-start2))
    print(("time elapse with AsParallel", elapse2))
except Exception as ex :
    logger.exception(ex)
finally:
    logger.debug(("time elapse without AsParallel", elapse1))
    logger.debug(("time elapse with AsParallel", elapse2))

Result file log

IronPython3Log.txt (6.0 KB)

3 Likes

Yes, I have the problem too, my self-written excel-codes don’t work with Python3 any more. :frowning:

What is the error? In order to help you we’d need the code and errors.

You’re going to have to add the reference in a way which is supported by the CPython library for the clr module.

Comment out everything but import clr, and then run OUT = dir(clr) to see what you can do.

You can comment out in bulk with the """ approach too :smiley:

stuffToKeep = [a, b, c]
#single line of comment out
"""
All stuff in here is commented out across 
all lines between 
the 
triple 
quotation marks
"""
3 Likes

Hello,

I would like to get viewport types but it does not work with Cpython3.

viewports = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Viewports).WhereElementIsNotElementType().ToElements()
type_ids = viewports[0].GetValidTypes()

TypeError: No method matches given argument for GetValidTypes (Class Autodesk.Reviut.DB.Viewport)

Any suggestion how to get the viewport types?

Hello,
Its an overload issue with PythonNet 2.5.2

2 Likes

Thank you ciril it works with the static method.

elementIds = List[ElementId](viewports)
validTypeIds = ElementType.GetValidTypes(doc, elementIds)
validTypes = [doc.GetElement(typeId) for typeId in validTypeIds]

But now I see that I can also call the types directly.

element_types = FilteredElementCollector(doc).OfClass(ElementType).ToElements()

for element_type in element_types:
    if hasattr(element_type, "FamilyName") and element_type.FamilyName == "Viewport":
        viewport_types.append(element_type)
2 Likes