Restore patching in unittest in Python

I like mocking and patching in unittest. And you shouldn’t forget to restore all the patchings also. I would think it should be put in the TearDown() method in a unittest. But it seems that I was wrong.

From the official document:

…This method will only be called if the setUp() succeeds, regardless of the outcome of the test method…

So if there is an exception in setUp(), the patchings will not be restored. The correct way of doing it should be using the addCleanup() method.

…If setUp() fails, meaning that tearDown() is not called, then any cleanup functions added will still be called.

And example if you use patch() as function.

class MyTest(TestCase):
    def setUp(self):
        patcher = patch('package.module.Class')
        self.MockClass = patcher.start()
        self.addCleanup(patcher.stop)

Setup a remote development environment with Vagrant, Salt and Digitalocean

For years I have been doing web development on a lenovo S10 netbook via SSH. I like to be able to connect to it from anywhere in the world and resume my work by typing: tmux -2u attach. But it also has some issues:

  1. sometimes the connection is very slow in other countries because I have to SSH to my home router in Sweden.
  2. the laptop is getting older and the fan makes lots of noise.
  3. I cannot do system snapshot like a virtual machine.
  4. I cannot suspend/resume the system remotely like a virtual machine.

Since I have been using Vagrant and Salt for my web service, I figured I could setup a remote development environment using Salt. All of my repositories are at Github and Bitbucket anyway. As for the VPS,  I chose DigitalOcean because of their API, price and speed:) Here is the github repository for my vagrant and salt files: https://github.com/zheli/dev-environment

Strange import error in Django

Last night I started to have a string Import Error in my Django project in the development environment. It was working before and I haven’t changed any code yet.

The Symptoms

I have a utils folder at the root of my django project with the following structure:

utils
|
|-__init__.py
|-log.py

And the problem appears in my code when I use:

from utils import log as logging

It gives me Import Error in some files but not all the files. Also if I use the shell I can load this module without problem. This whole thing is very strange. I checked the PYTHONPATH and PATH variable, but nothing seems to be wrong. So I created a new modules called libs with the same content and renamed the module name in all the code that complains import error.

Solution

I decided to try to look into it again today to see if it can be fixed, but I couldn’t find anyone who has the same problem like me. Accidentally, I found an interesting comment:

+1 just had similar problem to OP and removing *.pyc resolved it so thanks. this seems to work nicelyalias rmpyc="find . -name "*.pyc" -exec rm -rf {} \;" to ‘clean’ a project

And it worked! So it is because of the *.pyc I got when I was working in other branches. I don’t know when Python will decide to recompile the *.pyc file (or perhaps git removed the .py file, but left the .pyc file, and the code wasn’t cleaned up). But this is definitely something you need can try next time when you have an “Import Error”

Some tips with Raspberry Pi development

Change the permission for i2c

It is very annoying that you have to run your code with sudo to be able to use I2C. You can change it by doing this.

First add your user to i2c group:
sudo adduser pi i2c
then change the udev rules, here I changed rules for all the i2c devices. You have to edit 60-i2c-tools.rules file in your /lib/udev/rules.d/ folder.
sudo nano /lib/udev/rules.d/60-i2c-tools.rules
And change the following from
KERNEL=="i2c-[0-9]*", GROUP="i2c", MODE="0660"
to
KERNEL=="i2c-[0-9]*", GROUP="i2c", MODE="0666"
Save the file, type in the command below to reload udev rules.
sudo udevadm control --reload-rules

SimCan Python extension for CrossControl CCSimTech API

Not sure if anyone needs this:)

Finally finished my first Python extension written in C language. It was a good practice. I have forgotten a lot about C, especially the pointers:) So use this library at your own risk!

The library is compiled in Visual Studio 2008 Express Edition so it only supports 32bit Python 2.7.x. It also doesn’t support unicode. Should be enough for CAN message I guess. Another important thing to know is I am not sure whether it works with CCSimTech non-developer license. I might test it later after summer.

This library implemented CanOpen, CanClose and CanReceive functions.

The file and document can be found here.