雑記: パッケージが Windows 非対応だったときにごまかす話

昨日の記事では、並列させたくない処理を並列させないため、この世に1つだけの通行手形を発行するのに fcntl というパッケージを利用しました。しかし、実はこのパッケージは Windows に対応していません。昨日の記事の test.py(ワンオペ版)を Windows で実行すると、あなたは以下のメッセージに失望するでしょう。

ModuleNotFoundError: No module named 'fcntl'


しかし、「Windows では実行できません」として Windows ユーザを排除するのは昨今のダイバーシティの考え方に反していると思います。最低限、Windows でもコードを実行できるようにしたいものです。この世に1つの通行手形を発行してくれなくてもいいので――最悪そこは「Windows では並列実行しないでください」という注意書きで回避できるでしょう。実行できないよりは100倍ましです。

そういうわけで、Windows 用に fcntl のはりぼてをつくります。今回は以下のようなものでいいと思います。

fcntl_dummy/
 ├ fcntl/
 │ └ __init__.py
 └ setup.py

LOCK_EX = 0
LOCK_UN = 0

def flock(fd, operation):
    print('Dummy flock was called.')

from setuptools import setup

setup(
    name='fcntl.dummy',
    version='0.0.1',
    packages=['fcntl'],
)

fcntl のはりぼてが用意できたらそれを丸ごと tools のようなサブディレクトリの下に配置して、以下のように Pipfile を記述すればいいと思います。Windows でははりぼてをつかってほしいという指示になると思います。

project/
 ├ tools/
 │ └ fcntl_dummy/
 └ Pipfile


[[source]] name = "pypi" url = "https://pypi.org/simple" verify_ssl = true [packages] "fcntl_dummy" = {path = "./tools/fcntl_dummy", sys_platform = "== 'win32'"} [requires] python_version = "3.7"

Windows 機において上の Pipfile から環境をインストールして昨日のスクリプトを実行してみます。Windows でも実行できることがわかります。しかし、今回用意した fcntl のはりぼてには当然この世で1つの通行手形を渡す機能はなく、ばんばん通行を許可してくれるので、次郎の注文はブロッキングされず、太郎も次郎も10秒後にレストランを出ることができてしまいます。

$ pipenv install

$ pipenv run python test.py
太郎が店に来ました.
Dummy flock was called.
次郎が店に来ました.
Dummy flock was called.
Dummy flock was called.
太郎の注文ができました(5秒経過).
Dummy flock was called.
次郎の注文ができました(5秒経過).
太郎は食事を終えました(10秒経過).
次郎は食事を終えました(10秒経過).

なお、この Pipfile と Pipfile.lock を Linux 機にチェックアウトしてインストールした場合は、(はりぼて fcntl はインストールされませんので)ちゃんと次郎が店を出るのに15秒かかります。

$ pipenv install

$ pipenv run python test.py
太郎が店に来ました.
次郎が店に来ました.
太郎の注文ができました(5秒経過).
太郎は食事を終えました(10秒経過).
次郎の注文ができました(10秒経過).
次郎は食事を終えました(15秒経過).