Setting metaclass of wrapped class with Boost.Python - c++

I have an Event class defined in C++ that I expose to Python using Boost. My scripts are expected to derive from this class, and I'd like to do some initialization whenever a new child class is defined.
How can I set the metaclass of the exposed Event class such that whenever a Python script derives from this class, the metaclass could do the required initialization?
I would like to avoid having to explicitly use a metaclass in the scripts...
class KeyboardEvent(Event): # This is what I want
pass
class KeyboardEvent(Event, metaclass=EventMeta): # This is not a good solution
pass
Edit: Part of the solution
It seems there's no way to set the metaclass with Boost.Python. The next best thing is to improvise and change the metaclass after the class was defined. In native Python, the safe way to change a metaclass is to do this:
B = MetaClass(B.__name__, B.__bases__, B.__dict__)
In Boost, it'd look something like this:
BOOST_PYTHON_MODULE(event)
{
using namespace boost::python;
using boost::python::objects::add_to_namespace;
class_<EventMetaClass> eventmeta("__EventMetaClass")
...;
class_<Event> event("Event")
...;
add_to_namespace(scope(), "Event",
eventmeta(event["__name__"], event["__bases__"], event["__dict__"]));
}
The problem is that I can't seem to find a way to define a metaclass with Boost.Python, which is why I've opened How to define a Python metaclass with Boost.Python?.

If boost does not offer a way to do it from withn c++, and it looks like it don't, the way to go is to create wrapper classes that implement the metaclass -
It can be done more or less automatically usign a ittle bit of instrospection. Let's suppose your boost module is named "event" - you should either name the file as _event or place it inside you module, and write an python file - named "event.py" (or an __init__.py file on your module that would do more or less this:
import _event
class eventmeta(type):
...
event_dict = globals()
for key, value in _event.__dict__.items():
if isinstance(value, type):
event_dict[key] = eventmeta(key, (value,),{})
else:
#set other module members as members of this module
event_dict[key] = value
del key, value, event_dict
Thos cpde will automatically set module variables equal to any names found in the native"_event" module - and for each class it encounters, create a new class changing the metaclass, as in your example.
It may be that you get a metaclass conflict by doing this. If so, the way is to make the newly created classes to be proxies to the native classes, by creating proper __getattribute__ and __setattr__ methods. Just ask in a comment if you will need to do that.

Related

How to test signals when using factory_boy with muted signals

I am using factory_boy package and DjangoModelFactory to generate a factory model with muted signals
#factory.django.mute_signals(signals.post_save)
class SomeModelTargetFactory(DjangoModelFactory):
name = factory.Sequence(lambda x: "Name #{}".format(x))
...
I have a post_save signal connected to the model:
def send_notification(sender, instance, created, **kwargs):
if created:
send_email(...)
post_save.connect(send_notification, SomeModel)
How can I test the signals works when I create an instance of the model using the factory class?
Some solutions for the direct question. Followed by a caution.
A) Instead of turning off the signals, mock the side effects
#mock.patch('send_email')
def test_mocking_signal_side_effects(self, mocked_send_email):
my_obj = SomeModelTargetFactory()
# mocked version of send_email was called
self.assertEqual(mocked_send_email.call_count, 1)
my_obj.foo = 'bar'
my_obj.save()
# didn't call send_email again
self.assertEqual(mocked_send_email.call_count, 1)
Note: mock was separate package before joining standard lib in 3.3
B) Use as context manager so you can selectively disable in your tests
This would leave the signals on by default, but you can selectively disable:
def test_without_signals(self):
with factory.django.mute_signals(signals.post_save):
my_obj = SomeModelTargetFactory()
# ... perform actions w/o signals and assert ...
C) Mute signals and an extended version of the base factory
class SomeModelTargetFactory(DjangoModelFactory):
name = factory.Sequence(lambda x: "Name #{}".format(x))
# ...
#factory.django.mute_signals(signals.post_save)
class SomeModelTargetFactoryNoSignals(SomeModelTargetFactory):
pass
I've never tried this, but it seems like it should work. Additionally, if you just need the objects for a quick unit test where persistence isn't required, maybe FactoryBoy's BUILD strategy is a viable option.
Caution: Muting signals, especially like post_save can hide nasty bugs
There are easily findable references about how using signals in your own code can create a false sense of decoupling (post_save for example, essentially is the same as overriding and extending the save method. I'll let you research that to see if it applies to your use case.
Would definitely think twice about making it the default.
A safer approach is to "mute"/mock the receiver/side effect, not the sender.
The default Django model signals are used frequently by third party packages. Muting those can hide hard to track down bugs due to intra-package interaction.
Defining and calling (and then muting if needed) your own signals is better, but often is just re-inventing a method call. Sentry is a good example of signals being used well in a large codebase.
Solution A is by far the most explicit and safe. Solution B and C, without the addition of your own signal requires care and attention.
I wont say there are no use cases for muting post_save entirely. It should be an exception and an alert to maybe double check the need in the first place.

How to implicitly use the base definition of a method

I'm currently developping for python 2, and I'm trying to use abstract base classes to simulate interfaces. I have an interface, a base implementation of that interface and many subclasses that extend the base implementation. It looks like this:
class Interface(object):
__metaclass__ = ABCMeta
class IAudit(Interface):
#abstractproperty
def timestamp(self):
raise NotImplementedError()
#abstractproperty
def audit_type(self):
raise NotImplementedError()
class BaseAudit(IAudit):
def __init__(self, audit_type):
# init logic
pass
#property
def timestamp(self):
return self._timestamp
#property
def audit_type(self):
return self._audit_type
class ConcreteAudit(BaseAudit):
def __init__(self, audit_type):
# init logic
super(ConcreteAudit, self).__init__(audit_type)
pass
However PyCharm notifies me that ConcreteAudit should implement all abstract methods. However, BaseAudit (which is not specified as an abc) already implements those methods, and ­­­­ConcreteAudit is a subclass of BaseAudit. Why is PyCharm warning me? Shouldn't it detect that IAudit's contract is already implemented through BaseAudit?
Why is PyCharm warning you?
Because all Python IDEs suck, that's why.
Whenever an intern/junior programmer/peer tells me that something that I wrote isn't working for him, I tell him that I'm not discussing it until he tries it by executing a Python script from the command line or from the stock interpreter. 99% of the time, the problem disappears.
Why do they suck? Beats me. But they all sometimes hide exceptions, sometimes make it possible to have stuff imported you didn't know about, and all sometimes decide (as in this case) that something is problematic that a real program running on the stock interpreter simply won't have a problem with.
I tried you code in both Python 2.7 and Python 3.4, and as long as I add from abc import ABCMeta, abstractproperty at the top, it runs peachy-keen fine.
So just ditch PyCharm, or update the tags to show that's where the error is.

Ember: adding a mixin to a class after it's been created

I want to add a mixin to an Ember class which has already been created. (The class is defined in a library, actually Ember itself; it's LinkView).
I see that we can do mixin.apply(obj), but this applies the mixin to an instance of the class. I want to add the mixin to the class, so it's automatically mixed-in to all newly created objects.
I attempted to override the init method of the class, using reopenClass, and do mixin.apply(this) there, to apply the mixin to the instance, and then call the original init method, but this does not seem to work because the mixin wiring is set up in the init method and it's already too late by the time I can get to it.
reopenClass does not seem to accept a mixin argument like extend does. Its code seems to suggest that it's doing something with mixins, but whatever it is it doesn't work:
a = Ember.Object.extend().reopenClass(Ember.Mixin.create({mixval: 1});
a.create().get('mixval'); // undefined
I know that I could create my own class with MyLinkView = Ember.LinkView.extend(mixin, ..., but unfortunately the original class name is referenced explicitly within the library, so I really would prefer to figure out how to extend that original class with my mixin.
I experimented with Ember.LinkView = Ember.LinkView.extend(mixin, .... This somehow seems dangerous, although it seems to work. But in this particular case it doesn't help me since the reference within the Ember code (in the definition of the {{link-to}} helper) is to an internal version of the class, not the fully qualified Ember.LinkView.
Any ideas?
The solution is simply
Klass = Parent.extend({init: {...}});
Mixin = Ember.Mixin.create({init: {...}});
Klass.reopen(mixin);
Everything works as expected, including the super chain. In other words, a call to Klass.create().init() will call the mixin's init, and a call to super from there will call the original Klass#init.
In the course of researching this question, I discovered something interesting about reopen. Even if the argument is not a mixin, it is treated as one (internally, it actually creates a temporary one). This means that if you do
Klass.reopen({
init: function() {
this._super.apply(this, arguments);
}
});
The call to super is actually calling the original init, not the init in the parent class. In other words, specifying init in a reopen does not replace the existing init on the class, it more or less layers on top of it. I can't see this behavior documented anywhere in the Ember docs, but it does seem useful in the right situation.

How can I create a class method using AppleScriptObjC

I'm trying to override the +initialize method of a class using ASOC, but I cannot find a way to override a class method. Is it even possible?
Not to let any confusion possible about the language I'm talking about, here's some code:
script FLAppDelegate
property parent: class "NSObject"
-- -- Class Methods -- --
-- Insert code here
end script
I've done some tests, and as far as I can tell, weird as it is, methods defined using AppleScriptObjC are both class and instance methods.
Let's say I have an AppleScriptObjC file:
script iTunesController
property parent: class "NSObject"
on playpause()
tell application id "com.apple.iTunes" to playpause
end playpause
end script
In an Objective-C method, both:
- (void)callASOC
{
iTunesControllerInstance = [NSClassFromString(#"iTunesController") new];
[iTunesControllerInstance playpause];
[iTunesControllerInstance release];
}
and
- (void)callASOC
{
[NSClassFromString(#"iTunesController") playpause];
}
will call the playpause handler in the AppleScriptObjC file. The latter formulation will generate a warning a compile time, but works.
I was not able to find any documentation confirming or refuting this.
Thanks to #Friziab who reminded me of the NSClassFromString
So I could call a AppleScriptObjC method in my AppDelegate.applescript from another class (script) (NSView subclass)
I don't use AppleScriptObjC so there may be a proper way of doing it but this worked
current application's NSClassFromString("AppDelegate")'s popWindow()

fake directories for .net unit testing

I'm trying to create a unit test for a code similar to this:
foreach (string domainName in Directory.GetDirectories(server.Path))
{
HandleDomainDirectory(session, server, domainName);
}
The problem is that I'm using the System.IO.Directory class in my code.
How can I create a testing method that won't be dependent on any folder I have on my hard disk.
In other words, How can I fake the response of "Directory.GetDirectories(server.Path)"?
(Please note, I do control the "server" object in my class, therefore i can give any path i want)
Thanks.
Rather than calling Directory.GetDirectories(server.Path) directly, you could create an interface like IDirectoryResolver with a single method that takes a path string and returns the list of directories. The class containing your code above would then need a property or field of type IDirectoryResolver, which can be injected through the constructor or a setter.
For your production code, you would then create a new class that implements the IDirectoryResolver interface. This class could use the Directory.GetDirectories method in its implementation of the interface method.
For unit testing, you could create a MockDirectoryResolver class which implements IDirectoryResolver (or use a mocking library to create a mock instance for the interface). The mock implementation can do whatever you need it to do.
You would inject a wrapper class.
public class DirectoryFetcher
{
public virtual List<string> GetDirectoriesIn(string directory)
{
return Directory.GetDirectories(directory);
}
}
And then inject that:
foreach(string directory in _directoryFetcher.GetDirectoriesIn(server.Path))
{
// Whatever
}
You can then Mock that guy at the injection point (this example uses Moq, and constructor injection):
Mock<DirectoryFetcher> mockFetcher = new Mock<DirectoryFetcher>();
mockFetcher.Setup(x => x.GetDirectoriesIn("SomeDirectory")).Returns(new List<string>
{
"SampleDirectory1",
"SampleDirectory2"
});
MyObjectToTest testObj = new MyObjectToTest(mockFetcher.Object);
// Do Test
When communicating with the outside world, such as file system, databases, web services etc. , you should always consider using wrapper classes like the others before me suggested. Testability is one major argument, but an even bigger one is: The out side world changes, and you have no control over it. Folders move, user rights changes, new disk drives appears and old ones are removed. You only want to care about stuff like that in one place. Hence, the wrapper -- let's call it DirectoryResolver like Andy White suggested ealier.
So, wrap your file system calls, extract an interface, and inject that interface where you need to communicate with the file system.
The best solution I've found was to use Moles. The code is very specific, and must do very specific thing. Wrapping it with wrapper class will be redundant. The only reason I needed wrapper class is in order to write tests. Moles allows me to write the tests without any wrapper class :)