91

I received a Python project (which happens to be a Django project, if that matters,) that uses the fcntl module from the standard library, which seems to be available only on Linux. When I try to run it on my Windows machine, it stops with an ImportError, because this module does not exist here.

Is there any way for me to make a small change in the program to make it work on Windows?

Ram Rachum
  • 84,019
  • 84
  • 236
  • 374

3 Answers3

101

The substitute of fcntl on windows are win32api calls. The usage is completely different. It is not some switch you can just flip.

In other words, porting a fcntl-heavy-user module to windows is not trivial. It requires you to analyze what exactly each fcntl call does and then find the equivalent win32api code, if any.

There's also the possibility that some code using fcntl has no windows equivalent, which would require you to change the module api and maybe the structure/paradigm of the program using the module you're porting.

If you provide more details about the fcntl calls people can find windows equivalents.

mark4o
  • 58,919
  • 18
  • 87
  • 102
nosklo
  • 217,122
  • 57
  • 293
  • 297
  • Do you have information on whether using a single lock file for synchronization of other files is safe to do on Windows? We seem to still get race conditions after doing this despite the lock file locking and unlocking in an atomic manner just fine. It's like unlocking it does not create a happens-before guarantee for the other files we wrote while the lock was held. – Zyl Apr 05 '22 at 14:02
  • @Zyl the answer you're commenting on doesn't have anything to do with locks at all, it explains about `fcntl`/`win32api` calls, which can be used to do almost anything; I wouldn't believe anything is safe on windows; I suggest asking another question instead of commenting – nosklo Apr 07 '22 at 21:15
49

The fcntl module is just used for locking the pinning file, so assuming you don't try multiple access, this can be an acceptable workaround. Place this module in your sys.path, and it should just work as the official fcntl module.

Try using this module (source) for development/testing purposes only in windows.

def fcntl(fd, op, arg=0):
    return 0
        
def ioctl(fd, op, arg=0, mutable_flag=True):
    if mutable_flag:
        return 0
    else:
        return ""
    
def flock(fd, op):
    return
        
def lockf(fd, operation, length=0, start=0, whence=0):
    return

Of course, then you need to place the fcntl.py module in your site-packages directory for the Python interpreter that you want to use. For example, %LOCALAPPDATA%\Programs\Python\Python310\lib\site-packages\fcntl\. This is where my site-packages live. Check Tutorialspoint to find where yours is located.

Mavaddat Javid
  • 491
  • 4
  • 19
Muhammad Soliman
  • 21,644
  • 6
  • 109
  • 75
  • 3
    This is such a hack; but it's what I needed. :) – Tim Ludwinski Nov 13 '15 at 22:12
  • Added numeric constants. – Tim Ludwinski Nov 13 '15 at 22:46
  • 4
    How about fcntl.F_GETFD and fcntl.F_SETFD – JimSEOW Nov 18 '16 at 11:51
  • I know this is an old post but I found it useful in the last couple of days. Some variables were missing, I updated the code in the original message. – shlomiLan Dec 02 '17 at 18:31
  • 9
    link appears to be broken – Marc L. Jun 06 '19 at 17:23
  • 1
    How to add this to sys.path? I tried adding this on the same folder as my python script but it didnt work – luthfianto Jun 15 '20 at 13:58
  • @luthfianto you need to place it in your `site-packages` directory for the Python interpreter that you want to use. For example, `%LOCALAPPDATA%\Programs\Python\Python310\lib\site-packages\fcntl`. This is where my `site-packages` live. Check [Tutorialspoint](https://www.tutorialspoint.com/How-do-I-find-the-location-of-my-Python-site-packages-directory#:~:text=You%20can%20find%20the%20location%20of%20Python%20site-packages,run%20the%20following%20code%20in%20your%20shell%20%E2%88%92) to find yours. – Mavaddat Javid Jul 30 '22 at 18:31
17

Although this does not help you right away, there is an alternative that can work with both Unix (fcntl) and Windows (win32 api calls), called: portalocker

It describes itself as a cross-platform (posix/nt) API for flock-style file locking for Python. It basically maps fcntl to win32 api calls.

The original code at http://code.activestate.com/recipes/65203/ can now be installed as a separate package - https://pypi.python.org/pypi/portalocker

anatoly techtonik
  • 19,847
  • 9
  • 124
  • 140
Joeri
  • 171
  • 1
  • 2