Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to shadow python builtin pwd module

There is some python code that works under Linux. It uses the pwd module in a way like that:

import pwd
   ...
  def func():
      user=pwd.getpwnam(user)[2]

Now we have a specific need to cover this code with tests, and tests have to be runnable under Windows. The program itself is intended to run only under Linux. The problem is that pwd module is not available under Windows, so the code under test will fail with ImportError, even if the implementation of pwd functions is mocked using MagicMock.

The basic idea to solve this issue was to shadow the pwd module when running tests. So when running tests, the stub will shadow pwd and when running main program, original (Unix) pwd will be used. We created such stub at test PYTHONPATH:

# pwd.py
def getpwnam(user):
    print("YESSSSSSSS")

But it does not seem to shadow a pwd module, in a debugger we see that the built-in pwd is imported. I'm primarily a Java developer, so I'm sorry if the way of doing things is not "pythonic". Ideas are welcome.

like image 585
Dmitriusan Avatar asked May 13 '13 18:05

Dmitriusan


2 Answers

Rename your pwd.py to something else, such as winpwd.py. Then use:

try:
    import pwd
except ImportError:
    import winpwd as pwd

By importing pwd this way, you will get the built-in pwd on Linux, and winpwd on Windows. Then you should be able to run tests and mock it as you please.

like image 99
unutbu Avatar answered Sep 27 '22 17:09

unutbu


import os
if os.name == 'nt':
    class Pwd():
        def getpwnam(self, user):
            pass
    pwd = Pwd()
else:
    import pwd

Could something similar work? No need for extra .py files within your project.
I've used it for fchown myself a couple of times...

like image 34
Torxed Avatar answered Sep 27 '22 17:09

Torxed