def mma_run(cmd: str) -> str: mma_session.evaluate( wlexpr(f'''out=""; LinkWrite[kernel, EnterTextPacket[ MemoryConstrained[ TimeConstrained[Unevaluated[({cmd}) // InputForm],30,out=out<>"TLE(30s)"] ,268435456,out=out<>"MLE(256M)"] ] ];''')) time.sleep(5) return mma_session.evaluate( wlexpr(f''' TimeConstrained[ While[LinkReadyQ@kernel, temp=LinkRead[kernel]; Switch[temp, _TextPacket,out=out<>ToString[temp[[1]]]<>"\n", _ReturnTextPacket,out=out<>ToString[temp[[1]]]<>"\n", _ReturnPacket,out=out<>ToString[temp[[1,1]]]<>"\n", _OutputNamePacket,out=out<>ToString[temp[[1]]], _InputNamePacket,, _,out=out<>ToString[temp]<>"\n" ] ]; ,10,out="";out=out<>"输出时超时(10s)"]; out'''))
def _compute_eps(lam): session = WolframLanguageSession(wlpath) session.evaluate( wlexpr(''' randomgamma[alpha_, beta_, gamma_, samples_] := RandomVariate[GammaDistribution[alpha, beta, gamma, 0], samples]; ''')) random_gamma = session.function(wlexpr('randomgamma')) session.evaluate( wlexpr(''' integrant[exponents_, beta_, dimension_, clippingbound_, lam_, r_, q_] := Mean[NIntegrate[ (Sin[x]^(dimension-2)*Gamma[dimension/2]/(Sqrt[Pi]*Gamma[(dimension-1)/2]))*(((1-q)*(1-q+ q*Exp[(r^exponents-(r^2+clippingbound^2-2*r*clippingbound*Cos[x])^(exponents/2))/beta])^(lam)) +(q*(1-q+q*Exp[((r^2+clippingbound^2+2*r*clippingbound*Cos[x])^(exponents/2)-r^exponents)/beta])^(lam))),{x,0,Pi} ]]; ''')) integrant_moment = session.function(wlexpr('integrant')) samples = random_gamma(FLAGS.dimension / FLAGS.exponents, beta**(1 / FLAGS.exponents), FLAGS.exponents, FLAGS.num_samples) moment = integrant_moment(FLAGS.exponents, beta, FLAGS.dimension, FLAGS.clippingbound, lam, samples, FLAGS.q) eps = (FLAGS.T * mp.log(moment) + mp.log(1 / FLAGS.delta)) / lam session.terminate() return eps
def test_export(self): for value in ( 1, 2, "aaaa", 2.0, { 1: 2 }, [1, 2, 3], ["hello", decimal.Decimal("1.23")], wl.Foo, wl.Foo(2, wl.Context.Internal), ): self.serialize_compare(value, export(value, target_format="wxf")) self.assertEqual( export(Association(enumerate("abc")), target_format="wxf"), export( wl.Association(*(wl.Rule(i, v) for i, v in enumerate("abc"))), target_format="wxf", ), ) self.assertEqual( export(wlexpr("2+2"), target_format="wxf"), export(wl.ToExpression("2+2"), target_format="wxf"), ) self.assertEqual( export(wl.Foo(wlexpr("2+2"), 1, 2), target_format="wxf"), export(wl.Foo(wl.ToExpression("2+2"), 1, 2), target_format="wxf"), )
async def mma(session: CommandSession, supermode=False, kernel_on={}): # 获取设置了名称的插件列表 if session.event.detail_type == 'group' or session.event.user_id in SUPERUSERS: cmd = session.get('cmd', prompt='请输入命令?') # 首先是否关闭 if cmd == "Exit[]": if session.event.user_id not in SUPERUSERS: await session.send("错误: 权限不够, 无法关闭Wolfram Play.") elif (1 not in kernel_on): await session.send("错误: Wolfram Play已经是关闭状态.") else: mma_session.evaluate(wlexpr(f'LinkClose[kernel]')) mma_session.terminate() del kernel_on[1] await session.send("已成功关闭Wolfram Play.") # 然后输出状态 elif cmd == "State[]": await session.send(f"Wolfram Play是否启动: {1 in kernel_on}") # 都不是, 那么运行结果 else: if (1 not in kernel_on): kernel_on[1] = 0 mma_session.evaluate( wlexpr( f'kernel=LinkLaunch[First[$CommandLine] <> " -wstp -noicon"]' )) if (supermode and session.event.user_id in SUPERUSERS): await session.send(mma2_run(cmd)) else: FirstMaxLength = 200 out = mma_run(cmd) if (len(out) >= FirstMaxLength): pos = FirstMaxLength await session.send( f"输出总长{len(out)}字符. 前{pos}字符为:\n{out[:pos]}" ) #\n继续输出300字符请输入'y', 继续输出全部字符请输入'a', 从头全部输出请输入'A', 开启新的线程请等待{SESSION_EXPIRE_TIMEOUT}时间 或输入'n/N'. 只判断首字母.") state_dict = { 'y': 300, 'a': 2000, 'A': -1, 'n': -2, 'N': -2, } # while (pos < len(out)): # state = session.get('state', prompt=f'(此功能目前有bug →) 请继续/重新输入, 或等待线程超时.') # if state[0] in state_dict: # state_code = state_code[state[0]] # if state_code == -2: # break # elif state_code == -1: # await session.send(out) # break # else: # await session.send(out[pos:pos+state_code]) # pos += state_code else: await session.send(out) else: await session.send(f"错误: 权限不够, 无法使用mma.")
def test_input_form(self): self.compare(wlexpr('<|"2" -> 2|>'), b'(<|"2" -> 2|>)') self.compare( wl.Foo(2, wlexpr("#foo &")(wlexpr('<|"foo" -> 2|>'))), b'Foo[2, (#foo &)[(<|"foo" -> 2|>)]]', )
def addTopic(self): print(session.evaluate(wlexpr('''Keys[questionRepo["Easy"]]'''))) topic = self.ui.lineEdit_5.text() session.evaluate(wlexpr('''addNewTopic[ToString['''+str(topic)+''']]''')) self.ui.comboBox_4.addItem(topic) self.ui.comboBox_3.addItem(topic) session.evaluate(wlexpr('''Export["repo.mx",questionRepo]''')) print(session.evaluate(wlexpr('''Keys[questionRepo["Easy"]]''')))
def _(blk, _condition=wl.Equal(wl.Length(serv.thisAccount), 1)): blk.id = wl.Part( wl.Select( wl.Keys(blk.existingAccounts), Function( wlexpr("xxx"), wl.Equal(blk.existingAccounts[wlexpr("xxx")], blk.dataUser))), 1) # wolfram indices
def test_built_in_symbols(self): self.assertEqual(self.kernel_session.evaluate(wl.Null), None) self.assertEqual(self.kernel_session.evaluate(None), None) self.assertEqual(self.kernel_session.evaluate(wlexpr("None")), WLSymbol("None")) self.assertEqual(self.kernel_session.evaluate(wlexpr("True")), True) self.assertEqual(self.kernel_session.evaluate(True), True) self.assertEqual(self.kernel_session.evaluate(wlexpr("False")), False) self.assertEqual(self.kernel_session.evaluate(False), False) self.assertEqual(self.kernel_session.evaluate(wl.StringQ("foo")), True)
def deleteTopic(self): print(session.evaluate(wlexpr('''Keys[questionRepo["Easy"]]'''))) selectedTopic = self.ui.comboBox_3.currentText() topicIndex = self.ui.comboBox_3.currentIndex() self.ui.comboBox_3.removeItem(topicIndex) self.ui.comboBox_4.removeItem(topicIndex) session.evaluate(wlexpr('''deleteTopic[ToString['''+str(selectedTopic)+''']]''')) session.evaluate(wlexpr('''Export["repo.mx",questionRepo]''')) print(session.evaluate(wlexpr('''Keys[questionRepo["Easy"]]''')))
def test_built_in_symbols(self): self.assertEqual(self.kernel_session.evaluate(wl.Null), None) self.assertEqual(self.kernel_session.evaluate(None), None) self.assertEqual(self.kernel_session.evaluate(wlexpr('None')), WLSymbol('None')) self.assertEqual(self.kernel_session.evaluate(wlexpr('True')), True) self.assertEqual(self.kernel_session.evaluate(True), True) self.assertEqual(self.kernel_session.evaluate(wlexpr('False')), False) self.assertEqual(self.kernel_session.evaluate(False), False) self.assertEqual(self.kernel_session.evaluate(wl.StringQ('foo')), True)
async def bark(self, ctx,*, script): async with ctx.typing(): script = script.replace('```', '') try: # Set Up Whitelist using string of Wolfram code, only allowed functions specified here are able to execute (see WOLFRAM_WHITELIST.txt for formatted text for the following string) code = 'WHITELIST = {List, CompoundExpression, Set, SetDelayed, Blank, Pattern, Real, Complex, Hold, Sin, Cos, Plus, Times, Power, Log, Symbol, Integer, N, NIntegrate, Integrate, D, ReplaceAll, Rule, Style, FontFamily, Background, Plot, Graphics}; SetAttributes[whit, HoldFirst]; whit[REPLACE_] := Block[{i, k}, If[Length[Flatten[List[DeleteMissing[DeleteDuplicates[Evaluate[Map[Head, Level[Hold[REPLACE], {0, Infinity}]]/.Table[WHITELIST[[i]] -> Missing[], {i, Length[WHITELIST]}]] /. Missing[][u__] -> {u}]]]]] > 0, "Grrr, banned function(s)! " <> ToString[DeleteMissing[DeleteDuplicates[Evaluate[Map[Head, Level[Hold[REPLACE], {0, Infinity}]]] /.Table[WHITELIST[[k]] -> Missing[], {k, Length[WHITELIST]}] /. Missing[][u__] -> {u}]]], REPLACE]];' await session.evaluate(wlexpr(code)) export = wrap_wolf(script) # Evaluate given expression, exporting result as png eval = await asyncio.wait_for(session.evaluate_wrap(wlexpr(export)), 40) # Check for errors before sending result log = str(eval.messages) # Remove any (' and ') from error messages if '(\'' in log and ('\')' in log or '\',)' in log): log = log.replace('(\'', '') log = log.replace('\')', '') # Determine output when there's a wolfram error if log != 'None': if(len(log) > 256): await ctx.send(embed = embeds.general_error) elif (log).startswith('(\'Invalid syntax'): await ctx.send(embed = embeds.syntax_error) elif log.startswith('(\'Not enough memory available to rasterize Notebook expression.\',)'): await ctx.send(embed = embeds.memory_error) await ctx.send(f'```{await session.evaluate_wrap(wlexpr(script), timeout = 5)}```') else: log = embeds.createEmbed(log) ##################enlarge() if 'Animate' not in script: await ctx.send(file=discord.File(img_path)) else: await ctx.send(file=discord.File(f'{file}/output/output.gif')) await ctx.send(embed = log) else: # No errors, continue # Send image from Wolfram calculation results if 'Animate' not in script: await ctx.send(file=discord.File(img_path)) else: await ctx.send(file=discord.File(f'{file}/output/output.gif')) except exceptions.WhiteListError as error: await ctx.send(error.message) except exceptions.BlackListError as error: await ctx.send(error.message) except asyncio.TimeoutError: await ctx.send(embed = embeds.time_error) await session.evaluate(wlexpr('ClearAll["Global`*"]')) embeds.tail_message.description = f'Requested by\n{ctx.message.author.mention}' await ctx.send(embed = embeds.tail_message)
async def bark(self, ctx,*, script): async with ctx.typing(): script = script.replace('```', '') try: export = wrap_wolf(script) # Evaluate given expression, exporting result as png eval = await asyncio.wait_for(session.evaluate_wrap(wlexpr(export)), 40) # Check for errors before sending result log = str(eval.messages) # Remove any (' and ') from error messages if '(\'' in log and ('\')' in log or '\',)' in log): log = log.replace('(\'', '') log = log.replace('\')', '') # Determine output when there's a wolfram error if log != 'None': if(len(log) > 256): await ctx.send(embed = embeds.general_error) elif (log).startswith('(\'Invalid syntax'): await ctx.send(embed = embeds.syntax_error) elif log.startswith('(\'Not enough memory available to rasterize Notebook expression.\',)'): await ctx.send(embed = embeds.memory_error) await ctx.send(f'```{await session.evaluate_wrap(wlexpr(script), timeout = 5)}```') else: log = embeds.createEmbed(log) ##################enlarge() if 'Animate' not in script: await ctx.send(file=discord.File(img_path)) else: await ctx.send(file=discord.File(f'{file}/output/output.gif')) await ctx.send(embed = log) else: # No errors, continue # Send image from Wolfram calculation results if 'Animate' not in script: await ctx.send(file=discord.File(img_path)) else: await ctx.send(file=discord.File(f'{file}/output/output.gif')) except exceptions.WhiteListError as error: await ctx.send(error.message) except exceptions.BlackListError as error: await ctx.send(error.message) except asyncio.TimeoutError: await ctx.send(embed = embeds.time_error) await session.evaluate(wlexpr('ClearAll["Global`*"]')) embeds.tail_message.description = f'Requested by\n{ctx.message.author.mention}' await ctx.send(embed = embeds.tail_message)
def is_comb_in_base(comb, base): variable_string = "{" variables = [] constraint_string = "" constraints = [] item_constraints = ["" for j in range(len(comb))] for i in range(len(base)): variables.append("x{}".format(i)) constraints.append("x{} >= 0".format(i)) for j in range(len(comb)): if base[i][j] == 1: item_constraints[j] += "+ x{}".format(i) elif base[i][j] == -1: item_constraints[j] += " - x{}".format(i) opt_goal = item_constraints[0] for j in range(len(comb)): item_constraints[j] += " == {}".format(comb[j]) all_constraints = item_constraints + constraints constraint_string = "{" + ",".join(all_constraints) + "}" variable_string += ",".join(variables) + "}" lp_string = "Quiet[Maximize[" + opt_goal + ", " + constraint_string + "," + variable_string + "]]" is_feasible = session.evaluate(wlexpr(lp_string)) return type(is_feasible[0]) == int
def Text(s, fontSize=20, coords=(0, 0), offset=(0, 0), direction=(1, 0), color=wl.White): s = str(s) if (direction == (1, 0) or direction == ROTATE_90) and offset == (0, 0) and coords == (0, 0): # not specifying these makes Text function differently and actually work in some contexts, unfortunately t = wl.Style( wl.Text(s), color, FontSize(fontSize), ) else: t = wl.Style(wl.Text( s, coords, offset, direction, ), color, FontSize(fontSize)) if direction == ROTATE_90: t = Rotate( Rasterize( t, Background(), RasterSize(200), # ImageSize() ), wlexpr('90 Degree')) return t
def _(blk: WolframService, _condition=serv.xx["message"]['password'] == wl.Part( wl.CloudSymbol("APIPasswords"), self.apiFile.abspath)): blk._.exprs += [ wlexpr('CloudSymbol["APILog"] = "simple_admin_api: ABORT"') ] blk.abort()
def get_weather_info(self, text) -> dict: """ Returns a dictionary with some weather info for the first city found in the given (natural language) text. :param text: any text """ self.check_session() if text is None or len(text) == 0: return {} city = self.get_city(text) if city is None or len(city) == 0: return {} print(f"Found city: {city}") found = self.get_weather(city) if isinstance(found, dict) and found["Temperature"].args[0] != "NotAvailable": self.get_city_image(city) return { "Input": text, "City": city, "Temperature": found["Temperature"].args[0], "WindSpeed": found["WindSpeed"].args[0], "Pressure": found["Pressure"].args[0], "Info": self.session.evaluate(wlexpr(f'TextSentences[WikipediaData["{city}"]][[;; 5]]'))[0] } else: return {}
def test_cloud_service(): from wolframclient.language import wl, wlexpr print(session.evaluate(wl.Range(3))) print(session.evaluate(wl.StringReverse('abc'))) wl_str_reverse = session.function(wl.StringReverse) print(wl_str_reverse("hello")) print(wl_str_reverse("world.")) capital_distance = session.function( wlexpr('''\ QuantityMagnitude[ GeoDistance[ EntityValue[Entity["Country", #1], "CapitalCity"], EntityValue[Entity["Country", #2], "CapitalCity"] ], "Kilometers" ] & ''')) print(capital_distance('France', 'Japan')) print(capital_distance('Egypt', 'Peru')) api = ('*****@*****.**', 'api/private/xsquared') result = session.call(api, {'x': 4}) print(result.success) print(result.get())
async def bark(self, ctx, *, script): # Prepares the user input to be passed into Wolfram functions that export the output image, and limit the time of the computation async with ctx.typing(): # export = f'Export["{img_path}", Style[{script}, Large]]' try: log = await eval_input(script) # Remove any (' and ') from error messages if '(\'' in log and ('\')' in log or '\',)' in log): log.replace('(\'', '') log.replace('\')', '') # Determine output when there's a wolfram error if not await send_error(ctx, log): # No errors, continue enlarge() # Send image from Wolfram calculation results await ctx.send(file=discord.File(img_path)) except Exception: await ctx.send(embed=embeds.time_error) await session.evaluate(wlexpr('ClearAll["Global`*"]')) embeds.tail_message.description = f'Requested by\n{ctx.message.author.mention}' await ctx.send(embed=embeds.tail_message)
async def test_failed_expr(self): tasks = [ asyncio.create_task(self.pool.evaluate(wlexpr("Pause[.1]; 1/0"))) for i in range(1, 10) ] res = await asyncio.gather(*tasks) self.assertEqual(res, [wl.DirectedInfinity() for _ in range(1, 10)])
def manage(): cloud_files = weval(wl.CloudObjects(wlexpr('$CloudRootDirectory'))) for wcf in listmap(File, cloud_files): if wcf.abspath in _REGISTERED_SUBROOTS: pass elif wcf.abspath == _MAIN_SUBROOT: @log_invokation(with_args=True, stack=True) def recurse_cloud_file(sub_wcf): # f = File(f'{sub_wcf.abspath}') if not sub_wcf.exists: recurse_cloud_file.my_stacker.done = True if boolinput( f'{sub_wcf} is not mirrored locally, delete cloud file?' ): sub_wcf.wc.delete() if sub_wcf.wc.isdir: if Folder(sub_wcf)['.CLOUD_FILES.txt'].exists: Folder(sub_wcf)['.CLOUD_FILES.txt'].write('\n'.join( listmap( lambda e: e.abspath.replace( f'{Folder(sub_wcf).abspath}/', ''), sub_wcf.wc.files))) else: [recurse_cloud_file(c) for c in sub_wcf.wc.files] recurse_cloud_file(wcf) recurse_cloud_file.my_stacker.done = True else: err(f'{wcf.abspath} is not a registered Wolfram Cloud subroot')
def pb_solve2(comb, base): cnf = "" total = 0 all_clauses = [] con_ind = 0 for con in base + [comb]: con_ind += 1 rhs = -1 all_eq = [] all_str = "" for elem_ind in range(len(con)): elem = con[elem_ind] if elem != 0: for bit in range(1, 8): all_eq.append( pblib.WeightedLit(int("{}{}".format(elem_ind, bit)), 2**(bit - 1) * elem)) if elem > 0: all_str += "+ {} x{}".format( 2**(bit - 1) * elem, int("{}{}".format(elem_ind, bit))) else: all_str += "{} x{}".format( 2**(bit - 1) * elem, int("{}{}".format(elem_ind, bit))) all_str += " <= -1;" constr = pblib.PBConstraint(all_eq, pblib.LEQ, rhs) aux_var = pblib.AuxVarManager(10000 * con_ind) config = pblib.PBConfig() formula = pblib.VectorClauseDatabase(config) pb2cnf = pblib.Pb2cnf(config) pb2cnf.encode(constr, formula, aux_var) clauses = formula.get_clauses() all_clauses += clauses all_vars = set([]) all_clauses_str = [] for c in all_clauses: if not c: return clause_str = [] for var in c: all_vars.add("x{}".format(var)) clause_str.append("x{}".format(var)) clause = "(" + " || ".join(clause_str) + ")" all_clauses_str.append(clause) cnf = " && ".join(all_clauses_str) cnf_string = "SatisfiableQ[{}, ".format(cnf) + "{" + " {} ".format( ",".join(all_vars)) + "}]" res = session.evaluate(wlexpr(cnf_string)) print(res)
def mma2_run(cmd: str) -> str: return mma_session.evaluate( wlexpr(f''' MemoryConstrained[ TimeConstrained[({cmd}) // ToString,30,"TLE(30s)"] ,268435456,"MLE(256M)"] '''))
async def test_eval_wrap(self): start = time.perf_counter() task = asyncio.create_task( self.async_session.evaluate_wrap(wlexpr("Pause[.1]; Range[3]"))) timer = time.perf_counter() - start self.assertTrue(timer < 0.1) res = await task numpy.assert_array_equal(res.get(), numpy.arange(1, 4))
def normalize_input(self, expr): """ Normalize a given Python object representing an expr to as object as expected by evaluators. """ if self.inputform_string_evaluation and isinstance(expr, six.string_types): return wlexpr(expr) else: return expr
async def test_eval_wrap(self): start = time.perf_counter() task = asyncio.create_task( self.async_session.evaluate_wrap(wlexpr('Pause[.1]; Range[3]'))) timer = time.perf_counter() - start self.assertTrue(timer < .1) res = await task self.assertEqual(res.get(), [1, 2, 3])
def runPoint(self, paramsDict, threadNumber='0', debug=False): ''' ''' # Set up logging utility logFileName = 'SO11_Analysis-' + threadNumber + '.log' logging.basicConfig(level=logging.INFO, filename=logFileName) # Export the data rules to the Mathematica association filetype paramsDict_wl = export(paramsDict, pandas_dataframe_head='association') dataRuleExpr = wlexpr(bytes('dataRule=', 'utf-8') + paramsDict_wl) resOut = {} try: # Run the Mathematica Weinber Angle Code with open(self.mathScriptPath, 'r') as mathIn: strMath = mathIn.read() analysExpr = wlexpr(strMath) self.session.evaluate(dataRuleExpr) # print(paramsDict) timeConstrEval = wl.TimeConstrained(analysExpr, self.timeOut) resOut = self.session.evaluate(timeConstrEval) # resOut = self.session.evaluate(analysExpr) # resOut = wl.TimeConstrained(self.session.evaluate(analysExpr), 60) # print(resOut) except Exception as e: print(e) raise # print('-------') return {'Triviality': 1} # finally: # self.session.terminate() # print('Results for run: ', resOut) try: resStatus = resOut.name except Exception as e: resStatus = None if resStatus == '$Aborted' or bool(resOut) is False: return {'Triviality': 1} else: return resOut
async def bark(self, ctx, *, script): # Prepares the user input to be passed into Wolfram functions that export the output image, and limit the time of the computation async with ctx.typing(): export = f'Export["{img_path}", Style[{script}, Large], Background -> None, ImageResolution -> 100]' try: # Evaluate given expression, exporting result as png eval = await asyncio.wait_for( session.evaluate_wrap(wlexpr(export)), 40) # Check for errors before sending result log = str(eval.messages) # Remove any (' and ') from error messages if '(\'' in log and ('\')' in log or '\',)' in log): log.replace('(\'', '') log.replace('\')', '') # Determine output when there's a wolfram error if log != 'None': if (len(log) > 256): await ctx.send(embed=embeds.general_error) elif (log).startswith('(\'Invalid syntax'): await ctx.send(embed=embeds.syntax_error) elif log.startswith( '(\'Not enough memory available to rasterize Notebook expression.\',)' ): await ctx.send(embed=embeds.memory_error) await ctx.send( f'```{await session.evaluate_wrap(wlexpr(script), timeout = 5)}```' ) else: log = embeds.createEmbed(log) ##################enlarge() await ctx.send(file=discord.File(img_path)) await ctx.send(embed=log) else: # No errors, continue ######################enlarge() # Send image from Wolfram calculation results await ctx.send(file=discord.File(img_path)) except Exception: await ctx.send(embed=embeds.time_error) await session.evaluate(wlexpr('ClearAll["Global`*"]')) embeds.tail_message.description = f'Requested by\n{ctx.message.author.mention}' await ctx.send(embed=embeds.tail_message)
async def test_eval_inputform(self): tasks = [ asyncio.create_task( self.pool.evaluate(wlexpr("FromLetterNumber[%i]" % i))) for i in range(1, 11) ] res = await asyncio.gather(*tasks) self.assertEqual({*res}, {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"})
async def test_eval_wxf(self): start = time.perf_counter() task = asyncio.create_task( self.async_session.evaluate_wxf(wlexpr("Pause[.1]; Range[3]"))) timer = time.perf_counter() - start self.assertTrue(timer < 0.1) wxf = await task res = binary_deserialize(wxf) numpy.assert_array_equal(res, numpy.arange(1, 4))
def _py_wrap_result(r): if _py_is_non_primitive(r): return wlexpr('PyHandle[%d]' % py_state.put(r)) elif isinstance(r, types.GeneratorType): return _py_wrap_result(list(r)) elif isinstance(r, collections.abc.Sequence) and not isinstance(r, str): return type(r)([_py_wrap_result(x) for x in r]) else: return r