PythonNet define module from string - python.net

I'm using PythonNet to call a Python script from within a C# code.
I would like to define a module in a string variable (like myModule in the code below) and to be able to import that module and use its functions later:
using (Py.GIL())
{
// create a Python scope
using (PyScope scope = Py.CreateScope())
{
string myModule = #"# a lot of fancy Python code"; // Define a module here
// Here I'd like to register myModule as a module,
// to be used later within this scope: what shall I do?
string script = #"import myModule as functions"; // import and use the module here
scope.Exec(script);
...
string s = scope.Eval<string>(...);
return s;
}
}
How can this be achieved?

The PyScope class defines an overload of Import that accepts a PyScope and a string as parameters.
First, execute your module in a scope (moduleScope), then you can import it in a second scope
using (PyScope moduleScope = Py.CreateScope())
{
string myModule = #"# a lot of fancy Python code"; // Define a module here
moduleScope.Exec(myModule);
// create a Python scope
using (PyScope scope = Py.CreateScope())
{
scope.Import(moduleScope, "functions");
double d = scope.Eval<double>("functions.my_variable");
...

Related

Script binding does not work before calling Script.run()

I've the following test code to figure out how variable binding works. So this is what I want to import/include;
# importee.groovy
import groovy.transform.Field
#Field top = 60
number = 44 // binding variable
int ratio = 4.5
return this
which I call it from;
# importer.groovy (version1)
import groovy.lang.GroovyClassLoader
def gcl = new GroovyClassLoader()
def clazz = gcl.parseClass(new File("importee.groovy")) )
assert clazz.name == 'importee'
def script = clazz.newInstance()
//script.run()
println("binding variable:
${script.getBinding().getVariable("number")}")
So, if I don't run the script, my test code throws "MissingPropertyException" on the last print statement. This is not happenning if I call def script = evaluate(new File("importee.groovy")) instead of using GroovyClassLoader like this;
# importer.groovy (version2)
def script = evaluate(new File("importee.groovy"))
println("binding/global variable: ${script.number}")
Since both methods return a Script instance, I got a little bit confused on why I have to call the run() method in the first case. Can someone explain where I fail to understand please?
Thanks
run groovyconsole (distributed with groovy)
type a simple script:
number=44
return this
select menu Script -> Inspect Ast
and in the new window Groovy AST Browser select phase = Conversion
you will see your groovy script but converted to a Script class like this:
public class script1548245785832 extends groovy.lang.Script {
public script1548245785832() {
}
public java.lang.Object run() {
number = 44
return this
}
}
this is the actual code generated for your script.
as you can see the constructor is empty, so no information about number property after you call newInstance()
but after you call run() you actually run your script.
your script could be a class like this:
class Importee {
int number=44
public Object run(){
println number
}
}
in this case it will be enough to create instance of class without calling run() method and get the value of number variable...
def clazz = gcl.parseClass( new File("Importee.groovy")) )
def script = clazz.newInstance()
println("the variable: ${script.number}")

How to use scalajs-bundler with client only app

In another question I was advised to use ScalaJS bundler to import NPM dependencies.
I would like to use some Javascript NPM packages in a simple client-only web application. There is an example called static which shows this.
My changes to the example:
Add into build.sbt:
npmDependencies in Compile += "esprima" -> "3.1.3"
Add into Main.scala:
import Esprima._
import JsonToString._
val code = "answer = 42"
val tokens = tokenize(code)
val tokensStr = tokens.json
Change in Main.scala: "This is bold" into s"This is bold $tokensStr"
Facade (a bit simplified, for full a version see GitHub):
import scala.scalajs.js
import scala.scalajs.js.annotation.JSName
#JSName("esprima")
#js.native
object Esprima extends js.Object {
def tokenize(input: String, config: js.Any = js.native, delegate: String => String = js.native): js.Array[js.Any] = js.native
def parse(input: String, config: js.Any = js.native): js.Dynamic = js.native
}
When running the html generated with fastOptJS::webpack the error is:
Uncaught TypeError: Cannot read property 'tokenize' of undefined
Inspecting the static-fastopt-bundle.js shows esprima is used, but its js is not bundled.
What other steps are needed to add dependencies into a client-only web page?
As described in this part of the documentation, you have to use #JSImport in your facade definition:
#JSImport("esprima", JSImport.Namespace)
For reference, #JSName defines a facade bound to a global name, while #JSImport defines a facade bound to a required JavaScript module.

Issue creating a single .d.ts when using external modules

I'm developing an NPM package using typescript. Within this package the TS files are setup as external modules. The compiler won't generate a single .d.ts for external modules. I'm trying to concat all tsc generated type definitions into a single .d.ts for the entire package.
I'm having issues laying out the single .d.ts file (following a similar approach to that used in grunt-dts-bundle). The condensed example below captures my issue.
Given this external module declaration and test file:
test.d.ts :
declare module "ExternalWrapper" {
export import Foo = require("FooModule");
}
declare module "FooModule" {
class Foo {
name: string;
}
export = Foo;
}
test.ts:
import externalWrapper = require( 'ExternalWrapper' );
var t = new externalWrapper.Foo();
Running tsc test.ts test.d.ts -m commonjs produces this error: TS2083: Invalid 'new' expression.
If you change 'test.ts' to look like this, importing 'FooModule' directly:
import Foo = require( "FooModule" );
var t = new Foo();
It compiles fine.
The compiler understands the type externalWrapper.Foo however it doesn't seem to represent it as the same type FooModule.Foo. There is something I'm not getting about how the compilers handles modules that are exported via 'export import'.
Failing the above I'll probably look to manually creating the .d.ts :(
Any help appreciated.
You are probably missing a reference tag:
/// <reference path="test.d.ts"/>
It works :
You should be able to fix this by modifying your .d.ts file to resemble the following:
declare module "ExternalWrapper" {
import FooModule = require("FooModule");
export var Foo: typeof FooModule;
}
declare module "FooModule" {
class Foo {
name: string;
}
export = Foo;
}
With the export import syntax the compiler was assuming you were exporting an instance of Foo, not Foo itself... a little quirky.

How to mock the 'new' operator

I'm testing some groovy code that uses a java library and I want to mock out the library calls because they use the network. So the code under test looks something like:
def verifyInformation(String information) {
def request = new OusideLibraryRequest().compose(information)
new OutsideLibraryClient().verify(request)
}
I tried using MockFor and StubFor but I get errors such as:
No signature of method: com.myproject.OutsideLibraryTests.MockFor() is applicable for argument types: (java.lang.Class) values: [class com.otherCompany.OusideLibraryRequest]
I'm using Grails 2.0.3.
I've just found that we can always overwrite a constructor via MetaClass, as Grails 2 will be reset MetaClass modification at the end of each test.
This trick is better than Groovy's MockFor. AFAIK, Groovy's MockFor does not allow us to mock JDK's classes, java.io.File, for example. However in the below example, you cannot use File file = new File("aaa") as the real object type is a Map, not a File. The example is a Spock specification.
def "test mock"() {
setup:
def fileControl = mockFor(File)
File.metaClass.constructor = { String name -> [name: name] }
def file = new File("aaaa")
expect:
file.name == "aaaa"
}
The second, optional parameter to MockFor's constructor is interceptConstruction. If you set this to true, you can mock the constructor. Example:
import groovy.mock.interceptor.MockFor
class SomeClass {
def prop
SomeClass() {
prop = "real"
}
}
def mock = new MockFor(SomeClass, true)
mock.demand.with {
SomeClass() { new Expando([prop: "fake"]) }
}
mock.use {
def mockedSomeClass = new SomeClass()
assert mockedSomeClass.prop == "fake"
}
Note, however, you can only mock out groovy objects like this. If you're stuck with a Java library, you can pull the construction of the Java object into a factory method and mock that.

Unable to resolve this Compilation Error in Flex builder 3

I am new Web App development using Flex Builder 3 and currently I am facing the following problem:
Attached is a code snippet from the mxml file:
<mx:Script>
<![CDATA[
import com.bx.Char10;
import com.bx.A;
[Bindable] private var inputParam:A = new A()
inputParam.CustNumber.char10 = '0123456789'
}
]]>
</mx:Script>
This Gives a compile error
1120 Access of undefined property inputParam
However if I replace
inputParam.CustNumber.char10 = '0123456789'
with
private function set():void
{
inputParam.CustNumber.char10 = '0123456789'
}
The compile error goes away.
My Question is :
How can I remove this Compilation Error without using the workaround I did?
Hmm, I don't believe that one can execute arbitrary statements directly inside a class body. (The "Script" tag's contents are treated as if they were directly inside the class body).
Only function definitions or variable property definitions are allowed.
A different work-around to use is to pass the information through the constructor of the variable property you're interested in.
[Bindable] private var inputParam:A = new A('0123456789')