Python3でPitを使う

スクリプトを書くときに、パスワードを直接書いてしまうことがある。
これは、仕方がないことだと思っていたのだが、これを対策するものとしてPitというものをみつけた。

from pit import Pit
config = Pit.get('label', {'require':{'username':'your username','password':'your password'}})

Pythonではこのように書くことで

config[‘username’]=’your username’
config[‘password’]=’your password’
がセットされる。

しかしながら、Python3.4の環境ではこのようなエラーが出てきてしまった。

% python3
Python 3.4.1 (default, Nov  3 2014, 14:38:10) 
[GCC 4.9.1 20140930 (Red Hat 4.9.1-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pit import Pit
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
  File "<frozen importlib._bootstrap>", line 2222, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 2164, in _find_spec
  File "<frozen importlib._bootstrap>", line 1940, in find_spec
  File "<frozen importlib._bootstrap>", line 1916, in _get_spec
  File "<frozen importlib._bootstrap>", line 1897, in _legacy_get_spec
  File "<frozen importlib._bootstrap>", line 863, in spec_from_loader
  File "<frozen importlib._bootstrap>", line 904, in spec_from_file_location
  File "/usr/lib/python3.4/site-packages/pit-0.3-py3.4.egg/pit.py", line 34
    print 'No Changes'
                     ^
SyntaxError: invalid syntax

なんじゃこりゃ!

easy_install-3.4でPitをインストールしたのですがなんだか動かないみたいです。
でも、エラーをみてみると、どうやらPython2系で書かれているのが原因みたい。

ということで、ここからソースを拾ってきて以下のように修正をしました。
Python3仕様に書き換えただけです。

--- pit.py	2015-01-20 02:03:46.319152664 +0900
+++ pit_rev.py	2015-01-20 02:07:20.260474774 +0900
@@ -13,15 +13,15 @@
     def set(name, opts={}):
         profile = Pit._load()
         result = {}
-        if opts.has_key('data'):
+        if 'data' in opts:
             result = opts['data']
         else:
-            if not os.environ.has_key('EDITOR'):
+            if not 'EDITOR' in os.environ:
                 return {}
             
             temp_fd, path = tempfile.mkstemp()
             t = os.fdopen(temp_fd, "w")
-            c = yaml.dump(opts['config'] if opts.has_key('config') else Pit.get(name) ,default_flow_style=False)
+            c = yaml.dump(opts['config'] if 'config' in opts else Pit.get(name) ,default_flow_style=False)
             t.write(c)
             t.close()
             Popen([os.environ['EDITOR'],path]).communicate()
@@ -31,7 +31,7 @@
             os.remove(path)
 
             if result == c:
-                print 'No Changes'
+                print ('No Changes')
                 if name in profile:
                     return profile[nane]
                 return
@@ -47,8 +47,8 @@
     @staticmethod
     def get(name, opts={}):
         load_data = Pit._load()
-        ret = load_data[name] if load_data.has_key(name) else {} 
-        if opts.has_key('require'):
+        ret = load_data[name] if name in load_data else {}
+        if 'require' in opts: 
             keys = set(opts['require'].keys()) - set(ret.keys())
             if keys:
                 for key in keys:
@@ -72,13 +72,13 @@
     def _load():
         if not os.path.exists(Pit.DIRECTORY):
             os.mkdir(Pit.DIRECTORY)
-            os.chmod(Pit.DIRECTORY, 0700)
+            os.chmod(Pit.DIRECTORY, 0o700)
 
         if not os.path.exists(Pit._config):
             yaml.dump({'profile' : 'default'},
                       open(Pit._config, 'w'),
                       default_flow_style=False)
-            os.chmod(Pit._config, 0600)
+            os.chmod(Pit._config, 0o600)
 
         Pit.switch(Pit.config()['profile'])
 
@@ -86,7 +86,8 @@
             yaml.dump({}, 
                       open(Pit._profile, 'w'), 
                       default_flow_style=False)
-            os.chmod(Pit._profile, 0600)
+            os.chmod(Pit._profile, 0o600)
+            os.chmod(Pit._config, 0o600)
         return yaml.load(open(Pit._profile)) or {}
 
     @staticmethod
@@ -94,7 +95,7 @@
         return yaml.load(open(Pit._config))
 
 if __name__ == '__main__':
-    config = Pit.get('34twitter.com',{'require': {'email':'your email','password':'your password'}})
-    print config
-    print config['email']
-    print config['password']
+    config = Pit.get('34twitter.com',{'require': {'username':'your username','password':'your password'}})
+    print (config)
+    print (config['username'])
+    print (config['password'])

パッチを作りました。
pit_py3.diff

こんな感じでパッチを当ててからインストールしてください。

$ patch -u pit.py < pit_py3.diff
$ sudo python3 setup.py install

上記のパッチ適用済み
pit-0.3rev.tar.gz

easy_install用のEGGパッケージも作ってみました。
pit-0.3rev-py3.4.egg

easy_insatll-3.4で次のようにインストールしてください。

$ sudo easy_install-3.4 pit-0.3rev-py3.4.egg

最後にお好みで前のeggを削除してください

$ sudo rm /usr/lib/python3.4/site-packages/pit-0.3-py3.4.egg

実行結果

% python3
Python 3.4.1 (default, Nov  3 2014, 14:38:10) 
[GCC 4.9.1 20140930 (Red Hat 4.9.1-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pit import Pit
>>> Pit.get('34twitter.com',{'require': {'username':'your username','password':'your password'}})
#環境変数のEDITORにセットされているエディタが開く セットされていない場合はそのままreturnされる
No Changes
{'username': '', 'password': ''}

動きました!

追記:
先人がいらっしゃった!(なので、初回バージョンからこっそり付け足し。。。←
スクリプトから生パスワードを追い出す – Python Advent Calendar 2013
Python3.3.3rc1ということでしたが、Python3.4でも同じように動いたということで。

1 thought on “Python3でPitを使う”

Leave a Reply

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください