I am using the python Fire module with an abstract parent class and a child class. Not all functions are abstract, some functions do not need to be replicated for each child:
parent class
from abc import ABC, abstractmethod
class Foo(ABC):
#abstractmethod
def __init__(self, val=None):
# some initialisations
#abstractmethod
def fun1(self, file=None):
# Some calls
def fun2(self):
# Non abastract func... Some calls
child class (test.py)
import fire
from foo import Foo
class Child(Foo)
def __init__(self, val=None):
super().__init__(val)
# some initialisations
def fun1(file='path/to/file')
# do some stuff
if __name__ == '__main__':
fire.Fire(Child)
when I run python CLI with python -m test --help I do not get any COMMANDS i.e. Fire is not recognising any functions to run. However it is recognising the parent global variables and init flags to set so why is this happening?
try passing it the instantiated object instead like they do here
fire.Fire(Child())
Related
I'm trying to implement in Python the builder pattern with some fail safes. This fail safes would normally be implemented in OOP using interfaces and would restrict the user of using some methods before others or at all, unless the current object can be manipulated using this methods.
How can such fail safes be implemented in Python?
The Python Abstract Base Class module (ABC) allows for such restrictions. Using Python 3:
from abc import ABC, abstractmethod
class AbstractFoo(ABC):
#abstractmethod
def foo(self):
pass
class ConcreteFoo(AbstractFoo):
pass
if __name__ == "__main__":
c = ConcreteFoo()
Executing this script will result in the following error:
TypeError: Can't instantiate abstract class ConcreteFoo with abstract methods foo
This error can be resolved by providing an implementation of the foo method:
from abc import ABC, abstractmethod
class AbstractFoo(ABC):
#abstractmethod
def foo(self):
pass
class ConcreteFoo(AbstractFoo):
def foo(self):
print('Made it to foo')
if __name__ == "__main__":
c = ConcreteFoo()
c.foo()
Executing this script results in the following:
Made it to foo
I'm fairly new to python and currently attempting to write a unit test for a class, but am having some problems with mocking out dependencies. I have 2 classes, one of which (ClassB) is a dependency of the other (ClassC). The goal is to mock out ClassB and the ArgumentParser classes in the test case for ClassC. ClassB looks as follows:
# defined in a.b.b
class ClassB:
def doStuff(self) -> None:
# do stuff
pass
def doSomethingElse(self) -> None:
# do something else
pass
ClassC:
# defined in a.b.c
from .b import ClassB
from argparse import ArgumentParser
class ClassC:
b
def __init__(self) -> None:
arguments = self.parseArguments()
self.b = ClassB()
self.b.doStuff()
def close(self) -> None:
self.b.doSomethingElse()
def parseArguments(self) -> dict:
c = ArgumentParser()
return return parser.parse_args()
And finally, the test case for ClassC:
# inside a.b.test
from unittest import TestCase
from unittest.mock import patch, MagicMock
from a.b.c import ClassC
class ClassCTest(TestCase):
#patch('a.b.c.ClassB')
#patch('a.b.c.ArgumentParser')
def test__init__(self, mock_ArgumentParser, mock_ClassB):
c = ClassC()
print(isinstance(c.b, MagicMock)) # outputs False
# for reference
print(isinstance(mock_ClassB, MagicMock)) # outputs True
I read in the patch docs that it's important to mock the class in the namespace it is used not where it is defined. So that's what I did, I mocked: a.b.c.classB instead of a.b.b.classB, have tried both though. I also tried importing ClassC inside the test__init__ method body, but this also didn't work.
I prefer not mocking methods of ClassB but rather the entire class to keep the test as isolated as possible.
Environment info:
Python 3.6.1
Any help would be greatly appreciated!
Since i'm new to python i didn't know about class attributes. I had a class attribute in ClassC that held ClassB and an instance attribute in init that shadowed the class attribute.
I know multiprocessing.Process is analogous to threading.Thread and when I subclass multiprocessing.Process to create a process, I find that I don't have to invoke the __init__() method of the parent class. I have wrote a few test scripts and find some problems:
The _parent_pid variable is initialized in the __init__ method of multiprocessing.Process. However, if I don't invoke the init method of Process, I still could use this variable in the subclass.
I don't know why because in my opinion, if subclassing a parent class, the subclass could only get the methods of the parent but not the variables of the parent if the subclass don't call the init method in the parent class.
Why does the subclass of threading.Thread have to call the init method in the parent class before doing other things while the subclass of multiprocessing.Process not? I have read the source code of the both classes and think that it may be a reason that threads in Python have to use some synchronous mechanism under the hood while processes not.
The first script is part of the demonstration of the first problem and the second script is related to the two problems:
Script #1:
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
class Parent(object):
def __init__(self):
self.parent = 'parent'
def myprint(self):
print('Hi')
class Child(Parent):
def __init__(self):
# super(Child, self).__init__()
self.myprint()
def print_parent(self):
try:
print(self.parent)
except Exception:
print('No such a variable self.parent.')
if __name__ == '__main__':
child = Child()
child.print_parent()
Script #2:
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
import os
import time
import multiprocessing
class Test(multiprocessing.Process):
# def __init__(self):
# super(Test, self).__init__()
def run(self):
while True:
print('process: %s, pid: %d, ppid: %d' % (self.name, self.pid, self._parent_pid))
time.sleep(2)
if __name__ == '__main__':
for i in xrange(3):
process = Test()
process.start()
print('My pid is %d' % (os.getpid(),))
If a subclass doesn't define __init__() at all, the parent class __init__() is invoked - same as for any other method. Your Test class does not define __init__(), so when you construct a Test instance, multiprocessing.Process's (the parent class's) __init__() is invoked.
Your Parent/Child example is very different: there Child.__init__() is defined.
The same is true of threading.Thread subclasses (or any other subclasses of any other class). If a subclass doesn't define __init__() at all, then threading.Thread.__init__() is invoked. Indeed, I've routinely relied on that for years :-)
You need to call a parent class __init__() only if a subclass does define its own __init__().
I can't seem to get the Test1.test_something() in test2 to work.. not sure if it's because they are both inheriting from the same base?
Helper.py:
class baseTest(unittest.TestCase):
def setUp(self, param="Something"):
print param
pass
Test1.py
from Helper import baseTest
class test1(baseTest):
def setUp(self):
super(test1, self).setUp('foo')
def test_something(self):
assert 1 == 1, "One does not equal one."
Test2.py
from Helper import baseTest
import Test1
class test2(baseTest):
def setUp(self):
super(test2, self).setUp('bar')
def test_something(self):
Test1.test_somehing()
Now, I had this working previously, when I had the setUp for test1 and test2 within their classes, but once I had them both inherit from baseTest, I started getting a unbound method <method> must be called with Test instance as first argument (got nothing instead). Any suggestions?
The problem is that Test1.test_something() is an instance method, not a class method. So you can't just call it like that (besides, even if it is class method, it should have been Test1.test1.test_something).
One way to do it (without messing around with the unittest.TestCase mechanism):
Test2.py
import Test1
class test2(Test1.test1):
# whatever else
And you're done, test2 inherits Test1.test1.test_something() automatically. If you need your test2's test_something to do extra stuff, just do super(test2, self).test_something() within your overridden definition of test_something in test2 class.
Move the tests that are shared by both Test1 and Test2 classes into BaseTest:
test.py:
import unittest
import sys
class BaseTest(unittest.TestCase):
def setUp(self, param="Something"):
print param
pass
def test_something(self):
assert 1 == 1, "One does not equal one."
class Test1(BaseTest):
def setUp(self):
super(Test1, self).setUp('foo')
test2.py:
import test
import unittest
import sys
class Test2(test.BaseTest):
def setUp(self):
super(Test2, self).setUp('bar')
I have a top class and classes that extend the top class, but almost all methods from the child classes are from the top class (using inheritance, without reimplementation), so I don't have the methods in the child classes, how could I export them with dbus for each child class (with the name of each child class as part of dbus path)?
I will show a example code for clarify, my class structure is:
Window (main class)
|--WindowOne (child class)
|--WindowTwo
|--WindowThree
My interface for dbus is com.example.MyInterface and I would like to access each child class using: com.example.MyInterface.WindowOne, and for each child class I would like to access the methods, inclusive the inherited methods from the main class, like com.example.MyInterface.WindowOne.show and com.example.MyInterface.WindowOne.destroy.
In this code, I extend the child class 'WindowOne' with the 'Window' class, the methods show() and destroy() in the 'Window' are not re-implemented in 'WindowOne', but in this code I put the method show() to explain the problem, the way I get the code to work was this, I re-declare the method show() in child class, but this seems bad.
The big question maybe is: There is some way to use the decorator: #dbus.service.method('com.example.MyInterface.WindowOne') for classes (child classes in this case)?
The test source code:
# interface imports
from gi.repository import Gtk
# dbus imports
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
# Main window class
class Window(dbus.service.Object):
def __init__(self, gladeFilePath, name):
# ... inicialization
self.name = name
self.busName = dbus.service.BusName('com.example.MyInterface.', bus=dbus.SessionBus())
dbus.service.Object.__init__(self, self.busName, '/com/example/MyInterface/' + self.name)
def show(self):
self.window.show_all()
def destroy(self):
Gtk.main_quit()
# Child window class
class WindowOne(Window):
def __init__(self, gladeFilePath):
Window.__init__(self, gladeFilePath, "WindowOne")
#dbus.service.method('com.example.MyInterface.WindowOne')
def show(self):
self.window.show_all()
if __name__ == "__main__":
DBusGMainLoop(set_as_default=True)
gladeFilePath = "/etc/interface.glade"
windowOne = WindowOne(gladeFilePath)
Gtk.main()
After some experimentation, I realize something essential, that I don't find before in documentation: The path for exported methods don't need to have the same path of exported object! Clarifing: If the method is not reimplemented in the child class (WindowOne), I don't need to export it in the child class using #dbus.service.method('com.example.MyInterface.WindowOne') , for example, I just need to export the method in the main class (Window) using: #dbus.service.method('com.example.MyInterface.Window')
So I just need to use a fixed path when export the method of the top class Window, see in the fixed code below.
# interface imports
from gi.repository import Gtk
# dbus imports
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
# Main window class
class Window(dbus.service.Object):
def __init__(self, gladeFilePath, name):
# ... inicialization
self.name = name
self.busName = dbus.service.BusName('com.example.MyInterface.', bus=dbus.SessionBus())
dbus.service.Object.__init__(self, self.busName, '/com/example/MyInterface/' + self.name)
#dbus.service.method('com.example.MyInterface.Window')
def show(self):
self.window.show_all()
#dbus.service.method('com.example.MyInterface.Window')
def destroy(self):
Gtk.main_quit()
#dbus.service.method('com.example.MyInterface.Window')
def update(self, data):
# top class 'update' method
# Child window class
class WindowOne(Window):
def __init__(self, gladeFilePath):
Window.__init__(self, gladeFilePath, "WindowOne")
#dbus.service.method('com.example.MyInterface.WindowOne')
def update(self, data):
# reimplementation of top class 'update' method
if __name__ == "__main__":
DBusGMainLoop(set_as_default=True)
gladeFilePath = "/etc/interface.glade"
windowOne = WindowOne(gladeFilePath)
Gtk.main()
In the code for call the bus method, I just use like below:
bus = dbus.SessionBus()
dbusWindowOne = bus.get_object('com.example.MyInterface', '/com/example/MyInterface/WindowOne')
showWindowOne = dbusWindowOne.get_dbus_method('show', 'com.example.MyInterface.Window')
updateWindowOne = dbusWindowOne.get_dbus_method('update', 'com.example.MyInterface.WindowOne')
The method show is called in the top class Window, but is executed in the object WindowOne that is a child class.
And the method update is called in the child class WindowOne, because it is reimplementing the top class method.