ã¯ããã«
æšæºã©ã€ãã©ãªãå€éšã©ã€ãã©ãªã®æåãã»ãã®å°ãã ãå€ããŠã¿ããââã§ããããããã©ã€ãã©ãªã®ãã¡ã€ã«ãçŽæ¥æžãæãããããªãªã¹ããŒãªææ®µã¯åããããããŸãããããç¹ã«Pythonã®æšæºã©ã€ãã©ãªã¯æ°å€ãã®ãããžã§ã¯ãã§å©çšãããããŒãžã§ã³ã¢ãããäŸåé¢ä¿ãèãããšããªãã¹ãæãå ããã«å·¥å€«ããããã®ã§ãã
ãããªãšãã«äŸ¿å©ãªã®ããunittest.mock.patchã䜿ã£ããäžæçãªã¢ã³ããŒãããïŒMonkey PatchingïŒãã§ããããã䜿ãã°ãæšæºã©ã€ãã©ãªãçŽæ¥å€æŽããããšãªããäžéšã®é¢æ°ãã¡ãœããã®æåãããã®å Žéããã§æžãæããããšãã§ããŸãã
ä»åäŸãšããŠã玹ä»ããã®ã¯ãzipfileã¢ãžã¥ãŒã«ã§ãã¡ã€ã«åãShift JISãUTF-8ãšãã£ãå¥ãšã³ã³ãŒãã§Zipå
éšã«æ ŒçŽããããšãã£ãããããªèŠæãããªãããã¯ããã¯ã§ããæ¬æ¥zipfileã¯ASCIIãUTF-8ã§ãšã³ã³ãŒããã仿§ã®ããã§ãShift JISãªã©ä»»æã®æåã³ãŒããæ±ãã®ã¯å®¹æã§ã¯ãããŸãããããã§ãunittest.mock.patchã䜿ã£ãŠãäžæçã«zipfileå
éšã®ãšã³ã³ãŒãåŠçãå€ããŠããŸãããšããããã§ãã
æšæºã©ã€ãã©ãªãã³ããŒããŠæžãæããå¿ èŠã¯ãããŸãããããããžã§ã¯ãå šäœãžã®åœ±é¿ãæå°éã«æããªããææã®æåãå®çŸã§ããŸããçæçãªæ€èšŒãç¹å¥ãªèŠä»¶äžã§ã®ãã¹ãæãªã©ããã®ã¢ãããŒãã¯äºæ³ä»¥äžã«æçšã§ãã
以äžã§ã¯ããã®æ¹æ³ãã¡ãªãããå®çšäžã®ãã€ã³ãã«ã€ããŠã玹ä»ããŸãããããèªãã°ãæšæºã©ã€ãã©ãªãæžãæããããšãªããå¿ èŠãªãšãã ãæåãå·®ãæ¿ãããã¡ãã£ãšããè£ã¯ã¶ãã身ã«ã€ãã¯ãã§ãã
èæ¯
å
æ¥ãããæ€èšŒã§æ°ãã¿ãŒã³ã®Zipãã¡ã€ã«ãäœæããå¿
èŠãããããã®äžã§ãZipãã¡ã€ã«å
ã«æ ŒçŽããããã¡ã€ã«åã®ãšã³ã³ãŒããæç€ºçã«å€æŽãããããšããèŠä»¶ããããŸããããã®éãããã£ãšpythonãäœãã§ã¹ã¯ãªããçµãã§è©Šãã°ããããšæã£ãŠãããã§ãããå®éãã£ãŠã¿ããšZipFile.writestr()ã¡ãœããã«å¯ŸããŠãencode('shift_jis')ãããã¡ã€ã«åãçŽæ¥æž¡ãããšãããšãšã©ãŒãçºçããŠããŸããŸããã
åå ãæ¢ããšãzipfileã®å
éšå®è£
ã§ã¯ASCII以å€ã®æåã³ãŒããæ€åºããããšèªåã§UTF-8ãšããŠæ±ããããªåŠçãããããã§ãShift JISãçŽæ¥æ±ãããšãæ³å®ããŠããªãããã§ããã
ïŒåèïŒQiitaèšäº https://qiita.com/bicstone/items/14ef11e80cf8d36004c2 ã§ã¯ãæšæºã©ã€ãã©ãªãã³ããŒïŒä¿®æ£ããŠç¬èªã«å¯Ÿå¿ããææ³ã玹ä»ãããŠããŸããïŒ
ãšã¯ãããæšæºã©ã€ãã©ãªãçŽæ¥ãããããšã«ã¯æµæããããŸããå°æ¥çãªã¡ã³ããã³ã¹æ§ãç§»æ€æ§ãããŒãžã§ã³ã¢ããæã®åœ±é¿ãèãããšãããŸãã¹ããŒããªææ³ã§ã¯ãããŸãããããã§æ€èšããã®ããäžæçãªã¢ã³ããŒãããïŒMonkey PatchingïŒãã§ãã
unittest.mock.patchã䜿ã£ãäžæçãããåœãŠ
ããã§åœ¹ç«ã€ã®ãæšæºã©ã€ãã©ãªã«å«ãŸããŠããunittest.mock.patchæ©èœã§ããéåžžã¯ãã¹ãã³ãŒãã§å€éšAPIãã¯ã©ã¹ãã¡ãœãããªã©ã眮ãæããããã«çšããããŸããããã®patch()ã¯æ¬çªã³ãŒãã§ãäžæçãªãããåœãŠãšããŠäœ¿ãããšãå¯èœã§ãã(æ¬çªã§å©çšããããšãæšå¥šãããã®ã§ã¯ãããŸãããã)
å ·äœçãªã¢ãããŒããšããŠã¯æ¬¡ã®ãããªæµãã«ãªããŸãã
zipfile.ZipFileãzipfile.ZipInfoãšãã£ãå éšã®ã¡ãœãããŸãã¯å±æ§ã察象ã«ããã¡ã€ã«åãšã³ã³ãŒãåšãã®æåã倿Žãããpatch()ã䜿ã£ãŠãå¿ èŠãªç®æã ãæåãå·®ãæ¿ãããããã«ãããShift JISã§ã®ãã¡ã€ã«åæå®ãªã©ãäžæçã«å®çŸã§ããŸãã
ããšãã°ãpatch()ã¯ã³ã³ããã¹ããããŒãžã£ãšããŠå©çšã§ããã®ã§ã以äžã®ãããªã³ãŒãã§äžæçãªå€æŽã詊ã¿ãããšãã§ããŸãïŒãããŸã§ã€ã¡ãŒãžã§ãïŒã
from unittest.mock import patch
import zipfile
def my_encode_filename(filename):
# ããã§Shift JISãšã³ã³ãŒãã詊ã¿ããªã©ãç¬èªåŠçãè¡ã
try:
return self.filename.encode('ascii'), self.flag_bits
except UnicodeEncodeError:
return self.filename.encode('shift_jis'), self.flag_bits
with patch('zipfile.ZipInfo._encodeFilenameFlags', my_encode_filename):
with zipfile.ZipFile('test.zip', 'w') as zf:
zf.writestr('ãã¹ã.txt', 'å
容')
# ãã®ãããã¯å
ã§ã¯ãã¡ã€ã«åãç¬èªãšã³ã³ãŒãã£ã³ã°ã§æ±ããã
patch()ãããã¯ãæããã°ãå
ã®zipfileã®æåã«æ»ããããæšæºã©ã€ãã©ãªãçŽæ¥æžãæãããªã¹ã¯ãé¿ãã€ã€ãäžæçãªå®éšãæ€èšŒãè¡ããŸãã
ãªããã®ã¢ãããŒããæå¹ãªã®ã
- ã©ã€ãã©ãªæ¬äœã倿Žããªã
æšæºã©ã€ãã©ãªã®ãœãŒã¹ãã³ããŒã»ä¿®æ£ããæ¹æ³ã¯ãä¿å®æ§ãå°æ¥çãªPythonããŒãžã§ã³ã¢ããã§ã®äºææ§ç¶æãé£ãããªããŸãããã®ç¹ãunittest.mock.patchã䜿ãã°ãäžåãã¡ã€ã«ãããããã«åäœãã«ã¹ã¿ãã€ãºå¯èœã§ãã - 詊è¡é¯èª€ãç°¡å
ãã¹ãã³ãŒããæžããããªæèŠã§å€æŽç¹ã詊ãããããèšå®ãã¹ããšã³ã³ãŒãäžåãçŽ æ©ãçºèŠã§ããŸãããŸãããããã¯ãæããã°å éãã«ãªããããç°å¢ãæ±ããŸããã - çæçã»éå®çãªå¯Ÿå¿çãšããŠæå¹
æ¬çªéçšã§åžžçšããã®ã¯é¿ãããææ³ã§ãããäžæçãªæ€èšŒãç¹æ®ã±ãŒã¹ã®ãã¹ããšããŠã¯å€§å€æçšã§ãããã¡ãã£ãšã ãæšæºã©ã€ãã©ãªã®æåãå€ãããããªããŠèŠæã«ãŽã£ããã§ãã
ãŸãšã
æšæºã©ã€ãã©ãªã§æã£åãæ©ãç¬èªã®æåã远å ããã«ã¯ãunittest.mock.patchã«ããäžæçãªã¢ã³ããŒãããã䟿å©ãªå ŽåããããŸãã
ãã¡ãããæ¬è³ªçã«ã¯æšæºã©ã€ãã©ãªåŽã®å¶çŽãçè§£ããäžã§ããã®å¶çŽãåé¿ããèšèšãèããã®ããã¹ããããããŸããããšã¯ãããã¹ããŒãã£ãŒã«æ€èšŒããããã§ãŒãºã§ããã°ããã®ãããªãã¯ããã¯ãçŸå Žã§ã®åé¡è§£æ±ºã«åœ¹ç«ã€ã§ãããã
ä»åã¯ãPythonã®zipfileã§ãã¡ã€ã«åã®ãšã³ã³ãŒããå€ããããšããããããªèŠæã«å¯ŸããŠãäžæçãããåœãŠãšãããè£ã¯ã¶ããã玹ä»ããŸãããäœããã®çç±ã§æšæºã©ã€ãã©ãªãçŽæ¥æžãæããããªããæåãå€ãããå Žåãunittest.mock.patchã«ããã¢ã³ããŒãããã¯äžåºŠè©ŠããŠã¿ã䟡å€ã¯ããããã§ãã