Pythonnet implement interface with generic method - python.net

In pythonnet, I'm trying to implement an interface with a generic method.
To be more precise, I'm trying to implement an custom decoder in python, so I would like to implement IPyObjectDecoder, which has a generic TryDecode method.
Here is my skeleton for a DateTime <=> datetime toy sample:
from System import DateTime
from Python.Runtime import PyObjectConversions, IPyObjectEncoder, IPyObjectDecoder
from datetime import datetime
class DatetimeDecoder(IPyObjectDecoder):
__namespace__ = "Tests.Codecs"
def CanDecode(self, object_type, clr_type):
return (
object_type == datetime
and clr_type.Name == "DateTime"
and clr_type.Namespace == "System"
)
def TryDecode(self, value, out):
return (False, 1)
datetime_decoder = DatetimeDecoder()
PyObjectConversions.RegisterDecoder(datetime_decoder)
But this code fails on class definition with:
Failed: [undefined]TypeError: Method 'TryDecode' in type 'Tests.Codecs.DatetimeDecoder' from assembly 'Python.Runtime.Dynamic, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
I assume it comes from the genericity of the method (but maybe it's the out parameter as well - but for this one I understood I should have a dummy parameter and return a tuple), is it possible to do that in python ?
Thank you

Related

Ununderstood type variance using kotlin variance

I'm using generics to not reuse code and I' running into a lack of understanding for type generics. I have a class Writer (java code from another library).
public class Writer<T>
A class FileWriter (java code from another library)
public class FileWriter<D>{
FileWriter(Writer<D> writer){
this.writer=writer
}
public void append(D datum){
//Does something
}
}
Now I'm initiating this in kotlin:
val writer = FileWriter(Writer(AGenratedJavaClassThatIMplementsSpecificRecord::class.java))
I can now call writer.append with AGenratedJavaClassThatIMplementsSpecificRecord(). It works just fine
I would like to pass this writer to a function.
funDoSomethingExtra(writer: FileWriter<in SpecificRecord>)
This gives me an error that I do not understand.
Type mismatch: inferred type is FileWriter<AGenratedJavaClassThatIMplementsSpecificRecord!>! but FileWriter<in SpecificRecord> was expected
Changing this to
funDoSomethingExtra(writer: FileWriter<out SpecificRecord>)
Makes writers.append give the error
Required Nothing, found AGenratedJavaClassThatIMplementsSpecificRecord.
Without the use of methods, all works fine. Which details Am I missing? It is probably something small,
Kind regards,
Jelmew
This line of your code:
val writer = FileWriter(Writer(AGenratedJavaClassThatIMplementsSpecificRecord::class.java))
does not specify the type of the FileWriter, so it is inferred from your arguments to the constructors, so the type of writer is FileWriter<AGenratedJavaClassThatIMplementsSpecificRecord>.
Your signature funDoSomethingExtra(writer: FileWriter<in SpecificRecord>) is correct for calling a method on the writer that does something to a SpecificRecord or subtype of SpecificRecord. However, your
FileWriter<AGenratedJavaClassThatIMplementsSpecificRecord>
cannot be cast to a FileWriter<in SpecificRecord> because AGenratedJavaClassThatIMplementsSpecificRecord is a subtype of SpecificRecord, not a supertype. The compiler knows your file writer can consume AGenratedJavaClassThatIMplementsSpecificRecord, but it doesn't know it can consume the less-specific type SpecificRecord. There's the possibility of you calling some function of the subtype that doesn't exist in the supertype.
So to be able to pass your writer to this function, it needs to be a FileWriter<SpecificRecord> or FileWriter<in SpecificRecord>. You can't safely cast it after its type is already assigned, but you can assign it the proper type right at the declaration site instead of letting the compiler try to infer it:
val writer: FileWriter<SpecificRecord> = FileWriter(Writer(AGenratedJavaClassThatIMplementsSpecificRecord::class.java))

PyQt5: Why self.sender() returns the base object not the derived one sent it

I am writing a server/client code with PyQt5 sockets and I met a strange behavior
First, I derived a class from QTCPSocket, so that I abstract the usage of socket to my data frame, use encryption,..etc before sending the data
So, let this class = mySocket which is an inherited class from QTCPSocket
mySocket has some variables in its init, Ex: self.key. And as I do in all sockets, I connected its readyread signal to my slot of name: rxdata
Now, the problem.
inside rxdata, when I try to get the sender object ( using self.sender() ), what it returns is object of type QTCPSocket not as I was expecting a mySocket object. Which I don't understand
I tried to cast the QTCPsocket returned using qtcpsocketObj.class =mySocket
but the problem now, is mySocket.init() obviously not called, this the variables like self.key won't be defined.
What can I do to overcome this issue?
After a lot of search and debugging,
the problem wasn't from self.sender(). the problem was that the QTCPServer object returns QTCPSocket, and casting it using _ class _() as I did wasn't the right way.
The solution was to derive a class from QTCPServer and instead of making it return QTCPSocket, it will return mySocket class object ( the details is well explained in documentation)
Here is a sample code:
class myQTCPServer(QTcpServer):
def __init__(self,parent=None):
super(myQTCPServer, self).__init__(parent)
def incomingConnection(self,socketDescriptor):
newSock = mySocket(self)
newSock.setSocketDescriptor(socketDescriptor)
self.addPendingConnection(newSock)

Unmarshalling generic types with Json Spray in Akka Http

I have routes in Akka Http(Scala) project which are basically the same (CRUD operations) except for entities they operate on
I have my Json formats defined in JsonSupport trait like this:
trait JsonSupport extends SprayJsonSupport {
import DefaultJsonProtocol._
implicit val userJsonFormat = jsonFormat3(User)
}
Then I have a route defined which extends this trait, so it works fine if I use a concrete type, but as soon as I have a generic type it fails to compile:
def userRoute[T]: Route =
pathPrefix("users") {
post {
entity(as[T]) { user =>
with error:
could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[T]
I suspect that it can't find implicit value because the type is too broad.
What type constraints should I give the T so it would be able to resolve it?
Is there a way to solve it?
Cheers,
Leonti

Dart serializing immutable objects

I would like serialize this immutable class
class CatalogueItem {
final Uri source;
final DateTime analyis;
final Period fromTo;
CatalogueItem.create(this.source, this.analyis, this.fromTo);
}
But I cannot as it is not a simple class. From the web site https://www.dartlang.org/articles/serialization/
Simple: All of the objects to be serialized are data transfer objects
(DTOs) with a default constructor.
So I have to add a default constructor - which means I have to drop the final keywords and my class is no longer immutable.
class CatalogueItem {
Uri source;
DateTime analyis;
Period fromTo;
CatalogueItem.create(this.source, this.analyis, this.fromTo);
CatalogueItem(){}
}
Is there any way around this one?
I think the default constructor is only necessary for deserialization (never used a package for (de)serialization). Serialization shouldn't need it.
The default constructor is redundant because if the deserialization package needs a default constructor it obviously attempts to create an instance using the default constructor to afterwards set the field values, which can't work with final fields.
I don't know if a serialization package supports a custom toJson() method/fromJson() constructor but I think this would be the easiest way to go.
class CatalogueItem {
final Uri source;
final DateTime analysis;
final Period fromTo;
CatalogueItem.create(this.source, this.analysis, this.fromTo);
factory CatalogueItem.fromJson(Map json) {
return new CatalogueItem.create(
json['source'] == null ? null : Uri.parse(json['source']),
json['analysis'] == null ? null : DateTime.parse(json['analysis'])),
json['fromTo'] == null ? null : new Period.fromJson(json['fromTo']));
}
Map toJson() {
return {
'source': source == null ? null : '$source',
'analysis': analysis == null ? null : '$analysis',
'fromTo': fromTo == null ? null : fromTo.toJson();
}
}
https://github.com/google/built_value.dart may do what you want -- it is specifically for creating immutable classes and serializing them.
Note that this requires a slightly different form for the class. This is to allow built_value to generate an implementation for you, and serializers.
abstract class CatalogueItem
implements Built<CatalogueItem, CatalogueItemBuilder> {
static Serializer<CatalogueItem> get serializer
=> _$catalogueItemSerializer;
Uri get source;
DateTime get analyis;
Period get fromTo;
factory CatalogueItem([updates(CatalogueItemBuilder b)]) =
_$CatalogueItem;
CatalogueItem._();
}
The generated implementation is immutable (uses final), and also provides operator==, hashCode and toString.
More detailed example: https://github.com/google/built_value.dart/blob/master/example/lib/example.dart
One option is to read further in the article and use the serialization package, which does handle such cases.

Access method of extended type in Go

The follow codes produces "prog.go:17: c.Test undefined (type Child has no field or method Test)". (http://play.golang.org/p/g3InujEX9W)
package main
import "fmt"
type Base struct {
X int
}
func (b Base) Test() int {
return b.X
}
type Child Base
func main() {
c := Child{4}
fmt.Println(c.Test())
}
I realize Test is technically defined on Base, but should Child inherit that method?
the way to go for inheritance in go is using struct embedding with anonymous struct members.
Here is an adaption of your example.
Read about struct embedding and go's approach to inheritance etc here
The behaviour you encountered is expected and in sync with the golang specification, which explicitly states that:
The method set of any type T consists of all methods with receiver type T. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing anonymous fields, as described in the section on struct types. Any other type has an empty method set.