1

組み込みの Python インタープリターを Exim に追加しています。私は組み込み perl インターフェースをコピーしましたが、python は長い間コード化されてきた組み込み perl インタープリターと同じように動作することを期待しています。目標は、システム管理者が exim の標準 ACL コマンドを使用する代わりに、強力なスクリプト言語 (つまり python) で複雑な機能を実行できるようにすることです。これは、exim ACL 言語を使用して比較的単純なことを行うと非常に複雑になる可能性があるためです。

この記事の執筆時点での私の現在のコードはhttp://git.exim.org/users/tlyons/exim.git/blob/9b2c5e1427d3861a2154bba04ac9b1f2420908f7:/src/src/python.cにあります。システム管理者のカスタム python コードをインポートし、その中で関数を呼び出し、戻り値を処理できるという点で適切に機能しています (単純な戻り値の型のみ: int、float、または string)。ただし、python関数に渡される値はまだ処理されていません。これが私の質問の始まりです。

Python では、組み込みの Python 関数に渡す引数は、c API を使用して int、long、double、float、または string のいずれかに明示的にキャストする必要があるようです。問題は、システム管理者がその埋め込まれた python コードと exim の c 側に何でも入れることができることです。それらの変数の型が何であるかわかりません。Python は動的に型付けされることを知っているので、埋め込みコードに値を渡すときにそのコンプライアンスを維持したいと考えていました。しかし、私のテストではそのようには機能していません。

次の基本的な非常に単純な python コードを使用します。

def dumb_add(a,b):
        return a+b

...そして、exim ACL 言語からの呼び出しコードは次のとおりです。

${python {dumb_add}{800}{100}}

以下の C コードでは、簡潔にするために参照カウントを省略しています。 countは、渡す引数の数です。

pArgs = PyTuple_New(count);
for (i=0; i<count; ++i)
{
  pValue = PyString_FromString((const char *)arg[i]);
  PyTuple_SetItem(pArgs, i, pValue);
}
pReturn = PyObject_CallObject(pFunc, pArgs);

はい、**arg は文字列の配列 (この単純なケースでは 2 つの文字列) へのポインターです。問題は、2 つの値が python コードで文字列として扱われるため、その c コードが埋め込まれた python を実行した結果は次のようになることです。

${python {dumb_add}{800}{100}}

800100

Pythonを次のように変更すると:

def dumb_add(a,b):
        return int(a)+int(b)

次に、Python コードを実行したその C コードの結果は、期待どおりです。

${python {dumb_add}{800}{100}}

900

私の目標は、python ユーザーに、埋め込まれた python 関数に渡すすべての数値パラメーターを手動でキャストすることを強制したくないということです。PyString_FromString() の代わりに PyDynamicType_FromString() があれば、私は有頂天になるでしょう。Exim の組み込み perl は引数を解析し、自動的にキャストを行います。組み込みの python からも同じことを期待していました。私が期待していた動的型付けを提供するために、Pythonがこの引数の解析を行うことができるかどうか、誰かが提案できますか?

または、その動的な型付けを維持したい場合、私の唯一のオプションは、各引数を解析し、それをキャストする型を推測することですか? 私は本当に本当に本当にそのアプローチを避けたいと思っていました. それに関しては、「渡されたすべてのパラメーターは文字列であるため、実際に数値を渡そうとしている場合は、すべてのパラメーターを int()、float()、double()、または long() でキャストする必要があります」と文書化するだけです。 . ただし、常にコンマが後にありますが、このアプローチは私の実装で強力な Python コーダーを苦しめると思います。それも避けたい。

「アプリを python モジュールにする」以外のすべての提案を歓迎します。

4

1 に答える 1