Does the aasm state machine def need to be loaded once or many times for model class? - state-machine

For a model class with AASM state machine, there is following def in the model class:
class Job
include AASM
aasm do
state :sleeping, :initial => true, :before_enter => :do_something
state :running
state :finished
......
end
My question is that, does the aasm gem load the def above everytime when it is in need. Or just load the def once when the model class is initially loaded and use it repeatedly through out the rest of the session.

I think it depends on your environment settings.
Usually in development the classes are reloaded if something changed - in production mode these classes will be cached and only loaded once at startup.

Related

Can a class own a content manager in python?

I have a class that manages some shared resources and currently provides a get_X() and put_X() method to access the resources. A better interface for this would be to use a context manager for each resource as in
with ResourceManager.X() as x:
# do stuff
But my use is a QT5 Widget class that grabs the resource then it gets configured and has to release the resource when the widget is destroyed:
class MyWidget(QtGui.Widgets.QTableWidget):
def conf(self):
self.x = ResourceManager.get_x()
def closeEvent(self, event):
ResourceManager.put_x()
super().closeEvent()
So is there a more pythonic way analog to the context manager "with" construct to keep a resource allocated for the livetime of a class?
Note: Qt5 doesn't allow multiple inheritance
Update:
The Qt5 UI file loader doesn't allow passing arguments to __init__ so I have added the conf() method to configure custom widgets after the UI files are loaded. That's why the ResourceManager.get_x() isn't in __init__.
What I would like to do is to get rid of the put_x() call. I want the resource to be automatically freed by python when the class is deleted. There are many widgets and resources and it's easy to forget a put_x() somewhere so I don't want to balance get/put calls manually.
Another concern is exceptions when multiple resources are used. If the exception happens after say the 3rd resource then only those 3 should be released. Another thing I don't want to track manually.
Never used QT before, but the first thing that comes to my mind are the __init__ and __del__ methods, called respectively when a class instance is created and destroyed.
You could try the following:
class MyWidget(QtGui.Widgets.QTableWidget):
def __init__(self):
super().__init__()
self.x = ResourceManager.get_x()
def __del__(self):
ResourceManager.put_x()
super().__del__()
My unique concern is that QT actually deletes the class if it's not used anymore.
Try it and let me know
super().closeEvent()

Pytorch: Recover network with customized VGG model that was saved improperly

I am currently doing work with customizing the forward method for models. I was using some tutorial code that ran VGG. I did a few runs with the baseline model and it seemed to work fine. Afterwards, I replaced the forward method for the VGG using:
net.forward = types.MethodType(forward_vgg_new, net)
Unfortunately, the way that the tutorial code saves the models is:
state = {
'net':net,
'acc':acc,
'epoch':epoch,
}
...
torch.save(state, ...)
While This worked for the original tutorial code, loading no longer works for my custom models as I get:
AttributeError: 'VGG' object has no attribute 'forward_vgg_new'
I have since read from the documentation that it is better for me to save the model's state_dict:
state = {
'net':net.state_dict(),
'acc':acc,
'epoch':epoch,
}
...
torch.save(state, ...)
While I will change the code for future runs, I was wondering if it was possible to salvage the models I have already trained. I naively already tried to import the VGG class and add my forward_vgg_new method to it:
setattr(VGG, 'forward_vgg_new', forward_vgg_new)
before calling torch.load, but it doesn't work.
To solve the problem, I went directly into the VGG library and temporarily added my function so that I could load the saved models and save only their state dicts. I reverted the changes to the VGG library after I recovered the saves. Not the most graceful way of fixing the problem, but it worked.

Use DMXPY with a Transitions state machine

I am trying to use DmxPy with a state machine written in Transitions but trying to pass the DmxPy to the finite state machine is throwing a metaclass error. It seems output of DmxPy is a Nonetype which is not running within the Transitions state machine.
Does anyone know how to get the following simplistic, non-functioning script working or a variation to cause a light to turn on depending upon the state we are in?
class DmxPy:
def __init__(self, serialPort):
self.serial =serialPort(serialPort, baudrate=57600)
...other DMX code...
def set_red(self, channel)
...RGBW color red mix...
def set_green(self, channel)
...RGBW color green mix...
def render(self)
self.serial.write(...DMX code...)
The above is simplistic but to run it would be
dmx = DmxPy('COM5')
dmx.set_red(1)
dmx.render()
or
dmx = DmxPy('COM5')
dmx.set_red(1)
dmx.render()
The Transitions state machine code example, non-functional code is
class State:
pass
classFSMOpen(State, DmxPy):
dmx = DmxPy('COM5')
dmx.set_red(1)
dmx.render()
classFSMClosed(State,DmxPy):
dmx = DmxPy('COM5')
dmx.set_green(1)
dmx.render()
classFSM(object)
...creation of the FSM...
From the above code, I am receiving a TypeError: metaclass conflict and when I check the type of the DmxPy run code, it tells me it's a <class 'NoneType'>.
So, how can I use the DmxPy code within the FSM to change a light based on the state of the FSM? Or, does anyone have a better idea?
I have ciphered a way to make the code work, just not why. And I'm smart enough to not care at this point until the next time it breaks.
I simply changed the two classes by removing the call to the DmxPy code like so
class State:
pass
classFSMOpen(State):
dmx = DmxPy('COM5')
dmx.set_red(1)
dmx.render()
classFSMClosed(State):
dmx = DmxPy('COM5')
dmx.set_green(1)
dmx.render()
classFSM(object)
...creation of the FSM...
If someone has reason this worked, I'm all ears.

Mocking in Odoo environment?

Does anyone know how can you write mock tests for Odoo objects?
I have these classes and methods:
my_module:
from odoo import models
class MyModel(models.Model):
_name = 'my.model'
def action_copy(self):
IrTranslation = self.env['ir.translation']
for rec in self:
if rec.translate:
IrTranslation.force_translation(rec)
my_module_2:
from odoo import models
class IrTranslation(models.Model):
_inherit = 'ir.translation'
def force_translation(self, rec):
# do stuff
When I call it, I want to test if IrTranslation.force_translation was called in action_copy method and how many times.
But this method is not imported directly, it is referenced through env.
If let say force_translation would be imported like:
from my_module_2.IrTranslation import force_translation
def action_copy(self):
# do stuff.
force_translation()
Then I could try doing something like this:
from unittest import mock
from my_module import action_copy
def test_some_1(self):
with mock.patch('my_module.my_module_2.IrTranslation') as mocked_translation:
action_copy()
mocked_translation.force_translation.assert_called_once()
But because modules in Odoo are not imported directly (like you do it in plain Python), I don't understand how to specify methods in Odoo environment to be mocked.
P.S. I also did not see any mocked tests in standard Odoo, except for base classes that do not inherit Model class -> which then you need to use its _inherit attribute instead of importing class and passing it to be inherited on another class.
Testing in Odoo does not use the concept of mocking. Instead, tests are derived from standard base classes. The standard class TransactionalTest opens a transaction and never commits it, but rolls it back to undo any changes.
This is obviously not the same as regular mocking in that you can't replace other methods or classes to return fixed/expected values and/or avoid other side effects apart from persisting changes in the database, like sending emails or calling a remote web service.
It can be done. I do it all the time since Odoo 8.0 (until 15.0 now). The key is to know where to patch. Odoo adds odoo.addons to your module's package when its imported so in your case, you may do the following:
from odoo import tests
from mock import patch
from odoo.addons.my_module_2.models.ir_translations import IrTranslation
class TestMyModule2(tests.TransactionCase):
def some_test_1(self):
my_model = self.env['my.model'].create({})
with patch.object(IrTranslation, 'force_translation') as mocked_translation:
my_model.action_copy()
mocked_translation.assert_called_once()
Or using just patch, then no need to import:
with patch('odoo.addons.my_module_2.models.ir_translations.IrTranslation.force_translation') as mocked_translation:
my_model.action_copy()
This patches your specific method in your specific class. This way you can also target the method of a super class.
If you need to patch a method and you don't care where it is or where it's overriden, just patch using Python's type() (then no need to import class):
with patch.object(type(self.env['ir.translation']), 'force_translation') as mocked_translation:
my_model.action_copy()
Some additional notes to save you some headaches:
If you use pyCharm, don't mock socket objects. It messes with
pyCharm's mechanismes. Better to put your calls to socket into a one line
method and mock that method instead.
datetime.datetime.now() cannot be mocked, as all builtin types, but fields.Datetime.now() can.

Akka persistence- How do storage plugins work?

I have been going through the Akka persistence documentation. In the storage plug-ins i.e. Journal and Snapshot sections, I see that these plug-ins can be customized in the following way...
# Path to the journal plugin to be used
akka.persistence.journal.plugin = "my-journal"
# My custom journal plugin
my-journal {
# Class name of the plugin.
class = "docs.persistence.MyJournal"
# Dispatcher for the plugin actor.
plugin-dispatcher = "akka.actor.default-dispatcher"
}
How does the plug-in class work?? I tried to put some print statements in my custom journal plug-in class(in all the methods and in some static blocks) but none of them are executing. The same thing happened in the snapshot plug-in class.
Even if some superclass is using the overridden methods in this class, at least the print statements should be executed. Does this mean this class is never accessed? How do I know these classes are working??

Resources