Override parent class init value when using unittest mock - subclass

I have a class that is initialized like so:
class Parent:
def __init__(self, id):
self.network = id
self.requester = CompanyRequest()
To run tests for this class, I am mocking CompanyRequest so that I can define its return values. Since Parent only takes in id as a parameter I define a subclass:
class MockParent(Parent):
#patch("CompanyRequest")
def __init__(self, id, mock_request):
self.network = id
self.requester = mock_request
This works fine when testing and gives me the expected behavior. My issue is that for code review I get an error saying __init__ method from base class 'Parent' is not called. However if I call super().__init__(id) then it will try to call the real CompanyRequest instead of the mock_request, which causes all sorts of problems since the whole point of this is to test the Parent class methods on known return values.
Is there a way to override the parent __init__ function in a subclass? Or possibly a way to mock/bypass it?

Related

'this' in js and 'self' in python

The code to create a Set class in JS from a lesson Ive been working on uses !this.has(element)...in the add method. In the next line, it doesnt use 'this'. I am wondering when I am supposed to use 'this' on its own as in the add method or use it as 'this.variableName' or simply use the variable name on its own. I have the same questions about the methods in data structure classes in python only with 'self'. At times it uses self.variableName and other times not. Can anyone explain this to me? Thank you
self in python and this in JS are equivalent.
Both mean the class instance. When using self, you are explicitly using the class property against another property that can have the same name. Eg:
class MyClass:
value: int
def __init__(self, value):
self.value = value
def sum(self, value):
return self.value + value
myClass = MyClass(5)
print(myClass.sum(3)) # prints 8. In the sum method, self.value = 5 and value = 3.

Subclassing a class that has a "factory" method

I have a class that has a "factory" method which returns new instances given a file_name. Depending on the type of file given it needs to construct the object differently. It also happens to be a swig generated class wrapping a c++ class, I am not sure that matters, but I am including that detail just in case it does. So I have this class defined somewhere, which has among other things this new_from_file method
class Wv::WvWaveList
def self.new_from_file file_name
...
Wv::WaveList.new
end
....
end
I wanted to add a method copy_wave, so my first thought was to subclass and add it there so something like this.
class MyWaveList < Wv::WvWaveList
def copy_wave
...
end
end
The problem is that new_from_file still returns a Wv::WaveList not a MyWaveList so I can't call copy_wave on instances returned by new_from_file
One simple solution is to just open the class up here and add the method
class Wv::WvWave
def copy_wave
...
end
end
Another solution would be to have MyWaveList have an instance of a Wv::WaveList and delegate all the appropriate calls to that instance.
So I am just wondering what the inheritance solution might be? I just don't see it right now.
I believe this should work
class Wv::WvWaveList
def self.new_from_file file_name
...
self.new
end
....
end
Because self.new_from_file was always calling Wv::WaveList.new, it was always instantiating objects with that class, even from subclasses. But by using self, you'll be able to call new_from_file on any subclass, and the objects will be of the correct class:
>> a = MyWaveList.new_from_file "some_file"
=> #<MyWaveList:0x007fd473004318 #file_name="some_file">
>> a.class
=> MyWaveList

Saving instance list in class variable

I want to store newly created Person instance inside the class variable objects, but not sure how to reference the current instance from the constructor.
class Person
##objects = {}
def initialize(key)
##objects[key] = something
end
Ideally, the result is to be able to access the dictionary of Person objects through Person.objects
Simply, in constructor function, self will refer to the current instance.
class Person
##objects = {}
def initialize(key)
##objects[key] = self
puts self # it will print the id of the current instance
end
end
Same way, if you write self in a class method, it will refer to the the class.
But from your question, you seem to be doing something like Person.objects, and it won't work, and will output the following line:
NoMethodError: undefined method `objects' for Person:Class
So, you need to write a class method for it to let the outside world access objects.
def self.objects
##objects
end
Well, there are other ways as well to access the class variables, please have a look at this question.

Ruby. How to know which class instance method is defined?

I want to know which class method_missing is defined.
It is defined in Object.
How can I figure out which class along the hierarchy overrides it?
You can use UnboundMethod#owner method to check where the method is implemented:
class A
def method_missing(*args)
# do something
end
end
method = A.instance_method(:method_missing)
method.owner
# => A
Note: If the method is implemented in module (which is later mixed into the class hierarchy somewhere), owner will return this module.

How does automatic currying with self when assigning a method into a var work in Python 3?

I am writing a context manager to wrap the builtins.print function. And this works fine. However I encountered a Python behaviour that I can't wrap my head around:
Whenever a classes' method is assigned into a variable for later calling, the first "self" argument seems to be automatically stored as well and used for all later calls.
Here's an example illustrating the point:
import functools
class Wrapper:
def wrap(self):
return self._wrapped #functools.partial(self._wrapped, self)
def _wrapped(self, *args, **kwargs):
print('WRAPPED!', *args, **kwargs)
print('..knows about self:', self)
wrapped = Wrapper().wrap()
wrapped('expect self here', 'but', 'get', 'all', 'output')
The output:
WRAPPED! expect self here but get all output
..knows about self: <__main__.Wrapper object at 0x2aaaab2d9f50>
Of course for normal functions (outside of classes) this magic does not happen. I can even assign that method in the example above directly without going through instantiation:
wrapped = Wrapper._wrapped
wrapped('expect self here', 'but', 'get', 'all', 'output')
And now I get what I first expected:
WRAPPED! but get all output
..knows about self: expect self here
In my original code, I used the functools.partial to curry-in the self, but then discovered that this is not even required.
I like the current behaviour, but I'm not yet understanding the reasoning with respect to consistency and "being obvious".
I'm working with Python 3.1.2 here.
Is this question with the answer to use types.MethodType related? Searching here and in the 'net largely results in basic info on currying/partial function calls and packing/unpacking of arg lists. Maybe I used inadequate search terms (e.g. "python currying methods".)
Can anyone shed some light into this behaviour?
Is this the same in Py2 and Py3?
Whenever you take the method from an instance (as in return self._wrapped) then self will be remembered.
Whenever you take the method from a class (as in Wrapper._wrapped) then self is not (cannot be) remembered.
As an example, try this:
upper = 'hello'.upper
print(upper())
upper = str.upper
print(upper())
You'll see HELLO, followed by TypeError: descriptor 'upper' of 'str' object needs an argument
When an instance method is called, that call will automatically pass in the instance as the first parameter. This is what happens here.
When you do
return self._wrapped
You will return an instance method. Calling it will pass in the instance as the first parameter, that is self. But in the second case you call the method on the class, and hence there exists no instance to get passed in, so no instance gets passed in.
The "storage" of this is simply that instance methods know which instance they belong to. If you don't want that behavior return the unbound class method instead.
class Wrapper:
def wrap(self):
return Wrapper._wrapped
def _wrapped(self, *args, **kwargs):
print('WRAPPED!', *args, **kwargs)
print('..knows about self:', self)

Resources