Hi, I did a test case and filed an issue for it in the JIRA, test case uploaded there.
Best Regards /Petrus On Mon, Apr 8, 2019 at 9:00 AM Petrus Hyvönen <[email protected]> wrote: > Hi Andi, > > I will write a small test case for this. > > I think the best solution would be to sort the comparisons of types by > inheritance within the same number of parameters, but not sure how complex > this could end up. Maybe the IsInstanceOf method could be used to check if > there are such dependencies between the input parameters and then put the > ones lowest "level" first in the test. As I understand this would only be > needed at compile time, unless there are some dynamic types that will make > it very complex. > > Another alternative i guess would be to use very strict typing rules so it > really needs to be the same class of the types but that may affect how a > library is used alot. > > With Best Regards > /Petrus > > > On Sun, Apr 7, 2019 at 10:50 PM Andi Vajda <[email protected]> wrote: > >> >> On Sun, 7 Apr 2019, Petrus Hyvönen wrote: >> >> > Hi, >> > >> > I am getting inconsistent results and think I may be onto something. I >> am >> > doing builds both locally and in a online build server, where there >> should >> > be no old versions around. But both locally and there the results >> between >> > different runs varies even on same platforms. Sometimes I get the right >> > return type and for some builds and the same function returns its >> parents >> > for other build (same platform). >> > >> > I have looked at the generated code and there seems to be a difference >> in >> > the order of the parameter checking from the working vs non-working (no >> big >> > statistical ground however). >> > >> > For the working one, the child class type is checked before the parent. >> > Could it be that the parseArgs function gets a positive match when >> > comparing child with the parent? >> >> I think I understand what's going on but I'm not sure and having a small >> piece of code to reproduce the problem would help. >> >> Namely, when you have more than one overload for a given method that is >> valid for a given call then the order in which they're considered is >> probably (I didn't check) in the order the method signatures were >> returned >> by Java during the JCC compile. JCC sorts the overloads by number of args >> but then *does not* sort them by, say, lowest subclass in the tree first. >> This could be tricky, or even undecidable (or make things slower at >> runtime >> by trying to find the lowest match based on your python call - at the >> moment, the first valid match is returned). >> >> It is a bug for it to be random, however, so I think I should be able to >> get >> JCC to always succeed or fail in the same way, and not let the order of >> methods as returned by Java during compilation by JCC determine the >> behaviour. >> >> I could be wrong about this (the order returned by Java could be >> deterministic and well chosen and later broken by JCC, for example, I >> didn't >> yet check). >> >> You can help in getting this resolved by creating a small example that >> exhibits this bug (multiple overloads of a method that differ only in >> which >> piece of a subclass tree is used). >> >> You can also workaround this problem by using different method names to >> avoid such confusion with overloads (if that is indeed the problem). >> >> Andi.. >> >> > >> > Faulty return type (returns PVCoordinates type on >> TimeStampedPVCoordinates >> > input) >> > >> > >> > >> > ::org::orekit::utils::PVCoordinates a0((jobject) NULL); >> > >> > ::org::orekit::utils::PVCoordinates result((jobject) NULL); >> > >> > >> > >> > if (!parseArgs(args, "k", >> > ::org::orekit::utils::PVCoordinates::initializeClass, &a0)) >> > >> > { >> > >> > OBJ_CALL(result = self->object.transformPVCoordinates(a0)); >> > >> > return ::org::orekit::utils::t_PVCoordinates::wrap_Object >> > (result); >> > >> > } >> > >> > } >> > >> > { >> > >> > ::org::orekit::utils::TimeStampedPVCoordinates a0((jobject) >> NULL >> > ); >> > >> > ::org::orekit::utils::TimeStampedPVCoordinates >> result((jobject) >> > NULL); >> > >> > >> > >> > if (!parseArgs(args, "k", >> > ::org::orekit::utils::TimeStampedPVCoordinates::initializeClass, &a0)) >> > >> > { >> > >> > OBJ_CALL(result = >> self->object.transformPVCoordinates(a0)); // >> > Här är det det räknas ut >> > >> > return ::org::orekit::utils::t_TimeStampedPVCoordinates:: >> > wrap_Object(result); >> > >> > } >> > >> > } >> > >> > >> > >> > And corresponding code in a build that works: (TimeStampedPVCoordinates >> as >> > parameter gets return type TimeStampedPVCoordinates) >> > >> > static PyObject *t_Transform_transformPVCoordinates(t_Transform *self, >> > PyObject *args) >> > { >> > switch (PyTuple_GET_SIZE(args)) { >> > case 1: >> > { >> > ::org::orekit::utils::FieldPVCoordinates a0((jobject) NULL); >> > PyTypeObject **p0; >> > ::org::orekit::utils::FieldPVCoordinates result((jobject) NULL); >> > >> > if (!parseArgs(args, "K", >> > ::org::orekit::utils::FieldPVCoordinates::initializeClass, &a0, &p0, >> > ::org::orekit::utils::t_FieldPVCoordinates::parameters_)) >> > { >> > OBJ_CALL(result = self->object.transformPVCoordinates(a0)); >> > return ::org::orekit::utils::t_FieldPVCoordinates::wrap_Object(result); >> > } >> > } >> > { >> > ::org::orekit::utils::TimeStampedPVCoordinates a0((jobject) NULL); >> > ::org::orekit::utils::TimeStampedPVCoordinates result((jobject) NULL); >> > >> > if (!parseArgs(args, "k", >> > ::org::orekit::utils::TimeStampedPVCoordinates::initializeClass, &a0)) >> > { >> > OBJ_CALL(result = self->object.transformPVCoordinates(a0)); >> > return ::org::orekit::utils::t_TimeStampedPVCoordinates::wrap_Object >> > (result); >> > } >> > } >> > { >> > ::org::orekit::utils::TimeStampedFieldPVCoordinates a0((jobject) NULL); >> > PyTypeObject **p0; >> > ::org::orekit::utils::TimeStampedFieldPVCoordinates result((jobject) >> NULL); >> > >> > if (!parseArgs(args, "K", >> > ::org::orekit::utils::TimeStampedFieldPVCoordinates::initializeClass, >> &a0, >> > &p0, >> ::org::orekit::utils::t_TimeStampedFieldPVCoordinates::parameters_)) >> > { >> > OBJ_CALL(result = self->object.transformPVCoordinates(a0)); >> > return >> ::org::orekit::utils::t_TimeStampedFieldPVCoordinates::wrap_Object >> > (result); >> > } >> > } >> > { >> > ::org::orekit::utils::PVCoordinates a0((jobject) NULL); >> > ::org::orekit::utils::PVCoordinates result((jobject) NULL); >> > >> > if (!parseArgs(args, "k", >> > ::org::orekit::utils::PVCoordinates::initializeClass, &a0)) >> > { >> > OBJ_CALL(result = self->object.transformPVCoordinates(a0)); >> > return ::org::orekit::utils::t_PVCoordinates::wrap_Object(result); >> > } >> > } >> > } >> > >> > I guess there could be a zillion other reasons as well, but this would >> fit >> > with the random character on when it would work. >> > >> > I have tried to understand the parseArgs function but it is hard. >> > >> > Any comments welcome... >> > >> > With Best Regards >> > /Petrus >> > >> > >> > On Sat, Apr 6, 2019 at 3:58 AM Andi Vajda <[email protected]> wrote: >> > >> >> Are you sure you're running the code you think you're running ? Your >> >> description sounds like an old version of something may be picked up >> >> instead. >> >> >> >> Andi.. >> >> >> >>> On Apr 5, 2019, at 15:04, Petrus Hyvönen <[email protected]> >> >> wrote: >> >>> >> >>> Hi, >> >>> >> >>> I am having some confusing time with a wrapped class. >> >>> >> >>> The class "Transform" has a function transformPVCoordinates() that has >> >>> different options for input parameters. One of these are >> >>> TimeStampedPVCoordinates. It is supposed to return a >> >>> TimeStampedPVCoordinates object but returns instead a PVCoodinates >> object >> >>> that is its parent class. I cannot cast this to >> TimeStampedPVCoordinates, >> >>> gets an error. On most systems. On python 2.7 it works and only 3.6 >> under >> >>> linux (testing for max, linux and win). It worked also in Python 3.7 >> on >> >>> mac/windows for the JCC 3.0 version. >> >>> >> >>> I've checked the code being generated, and the return type and >> parameter >> >>> type of TimeStampedPVCoord are there, both in c code and .h file. >> >>> >> >>> How/where is the matching of parameters from python call done? I get a >> >>> feeling that the parent class is somehow used, but not shure how to >> >>> troubleshoot this... >> >>> >> >>> Best Regards >> >>> /Petrus >> >>> >> >>> >> >>> -- >> >>> _____________________________________________ >> >>> Petrus Hyvönen, Uppsala, Sweden >> >>> Mobile Phone/SMS:+46 73 803 19 00 >> >> >> >> >> > >> > -- >> > _____________________________________________ >> > Petrus Hyvönen, Uppsala, Sweden >> > Mobile Phone/SMS:+46 73 803 19 00 >> > > > > > -- > _____________________________________________ > Petrus Hyvönen, Uppsala, Sweden > Mobile Phone/SMS:+46 73 803 19 00 > -- _____________________________________________ Petrus Hyvönen, Uppsala, Sweden Mobile Phone/SMS:+46 73 803 19 00
