Werkzeug: reloader์—์„œ ํ˜ธ์ถœ๋œ Windows console_scripts

์— ๋งŒ๋“  2017๋…„ 06์›” 13์ผ  ยท  14์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: pallets/werkzeug

python 3์—์„œ apistar๋ฅผ ์‹คํ–‰ ์ค‘์ด๊ณ  werkzeug ๋ฆฌ๋กœ๋”๋กœ ์ด์–ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

(fresh) C:\Users\uskaxb07\PycharmProjects\testapi>apistar run
Starting up...
 * Restarting with stat
  File "C:\Users\uskaxb07\env\fresh\Scripts\apistar.exe", line 1
SyntaxError: Non-UTF-8 code starting with '\x90' in file C:\Users\uskaxb07\env\fresh\Scripts\apistar.exe on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

์ œ๊ฑฐ ์ค‘ use_reloader ๋กœ ํ˜ธ์ถœ์—์„œ์„ run_simple() ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ช‡ ๊ฐ€์ง€ ์˜๊ฒฌ์„ ํŒŒํ—ค์นœ ํ›„ https://github.com/pallets/werkzeug/blob/master/werkzeug/_reloader.py#L118 ์ด latin1์— ๋Œ€ํ•œ ์ธ์ฝ”๋”ฉ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์ง€๋งŒ OS๊ฐ€ Windows์ด๊ณ  ํŒŒ์ด์ฌ ๋ฒ„์ „์ธ ๊ฒฝ์šฐ์—๋งŒ ํ•ด๋‹น is 2. ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ python3์—์„œ ๋ฐ›๋Š” ๋น„ UTF-8 ๊ตฌ๋ฌธ ์˜ค๋ฅ˜์˜ ์›์ธ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ชจ๋“  14 ๋Œ“๊ธ€

์ด๊ฒƒ์„ ์žฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์€ ์˜ˆ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? apistar ์‚ฌ์šฉ์— ์ต์ˆ™ํ•˜์ง€ ์•Š๊ณ  Windows๋ฅผ ์ •๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์กฐ๊ธˆ ๋” ํŒŒ๊ณ ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ์‹ค์ œ๋กœ _get_args_for_reloading() ์ž…๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” subprocess.call() ์ „๋‹ฌ๋  ๋•Œ ํ•ด๋‹น ์˜ค๋ฅ˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” ['python.exe', 'apistar.exe', 'run'] ์ธ ์ธ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ช…๋ น์ค„์—์„œ python.exe apistar.exe run ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฌธ์ œ๋Š” ๋‚ด๊ฐ€ ์›๋ž˜ ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ๊ณผ ๊ฐ™์€ ํ™˜๊ฒฝ ์ธ์ฝ”๋”ฉ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‹ค๋ฅธ werkzueg ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋งค์šฐ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ console_script์—์„œ ์ƒ์„ฑ๋œ .exe๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊ณ ๋ คํ•˜์—ฌ ์ด ๋ฐฉ๋ฒ•์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ชจ๋“  Windows ์‚ฌ์šฉ์ž์—๊ฒŒ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์„ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ๋ฌธ์ œ ์ œ๋ชฉ์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฉ”์„œ๋“œ๊ฐ€ Windows ๊ฒ€์‚ฌ ๋‚ด์—์„œ rv์˜ sys.executable ์š”์†Œ๋ฅผ ์‚ญ์ œํ•˜๋ฉด ๋‹ค์‹œ ๋กœ๋“œ๊ฐ€ ์„ฑ๊ณตํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

def _get_args_for_reloading():
    """Returns the executable. This contains a workaround for windows
    if the executable is incorrectly reported to not have the .exe
    extension which can cause bugs on reloading.
    """
    rv = [sys.executable]
    py_script = sys.argv[0]
    if os.name == 'nt' and not os.path.exists(py_script) and \
       os.path.exists(py_script + '.exe'):
        py_script += '.exe'
        rv.pop()
    rv.append(py_script)
    rv.extend(sys.argv[1:])
    return rv

PR์„ ์ œ์ถœํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๊ธฐ๊บผ์ด ๊ฒ€ํ† ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ํ™•์‹คํžˆ ํ•˜๊ณ  ์‹ถ์ง€๋งŒ ์ด๊ฒƒ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ์•ฝ๊ฐ„ ๋ง‰ํ˜”์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด unittest.mock ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๊ณ  sys.executable ๋ฐ os.name์„ ํŒจ์น˜ํ•˜๋Š” ๊ฒƒ๋งŒ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ 27์—์„œ๋„ ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ๋ฅผ ์ง€์›ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์ด ํ”„๋กœ์ ํŠธ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ์ถฉ๊ณ ?

๋˜ํ•œ ์—ฌ๊ธฐ์— ์‚ฌ์šฉ๋œ ๋ถ„๊ธฐ ์ „๋žต์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋ฌธ์ œ์— ๋Œ€ํ•œ pull ์š”์ฒญ์€ ํ˜„์žฌ ์œ ์ง€ ๊ด€๋ฆฌ ๋ถ„๊ธฐ์— ์ ์šฉ๋ฉ๋‹ˆ๊นŒ?

0.12-maintenance์—์„œ ๋ถ„๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ํŒจ์น˜๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€ ํ™•์ธํ•œ ๋‹ค์Œ ํ…Œ์ŠคํŠธ๋ฅผ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค. Travis CI๊ฐ€ ๋‚ด๊ฐ€ ๋ณ€๊ฒฝํ•œ ๊ฒƒ๊ณผ ๊ด€๋ จ์ด ์—†๋Š” ์ด์œ ๋กœ ์‹คํŒจํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋Š” ์ด๋ฒˆ์ด ์ฒ˜์Œ์ด๋ผ ์–ด๋””์„œ๋ถ€ํ„ฐ ํ•ด์•ผํ• ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ setuptools์— exe ์‹คํ–‰ ํ”„๋กœ๊ทธ๋žจ์ด ์„ค์น˜๋˜์–ด ์žˆ์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ตœ์‹  pip๋ฅผ ํ†ตํ•ด ์„ค์น˜ํ•˜๋ฉด Python์ด ์ง์ ‘ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” zip( runpy docs ) ๋‚ด๋ถ€์˜ exe์— ์‹คํ–‰๊ธฐ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฒˆ๋“ค๋กœ ๋ฌถ๋Š” ์ƒˆ๋กœ์šด ์ข…๋ฅ˜์˜ exe ์‹คํ–‰๊ธฐ(

์ด๊ฒƒ์€ ์ด๊ฒƒ์ด ์ˆ˜์ •๋˜์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ์ด๊ฒƒ์„ ์žฌํ˜„ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๋ฅผ ์•„๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Flask๋ฅผ ๊ฐœ๋ฐœ ๋ชจ๋“œ( pip install -e )๋กœ ์„ค์น˜ํ•˜๋ฉด ๊ณ„์† ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

@androiddrew @davidism ์ด PR์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@segevfiner ๊ฐ€์žฅ ์ตœ๊ทผ ๋Œ“๊ธ€์— ์ข€ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? Flask๊ฐ€ ์•„๋‹Œ setuptools์—์„œ ๊ทผ๋ณธ ์›์ธ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ œ์•ˆํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

@ewpete ๊ทผ๋ณธ ์›์ธ์€ setuptools์—์„œ ์ƒ์„ฑ๋œ ๋Ÿฐ์ฒ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ,
sys.argv[0]์€ Python ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
๋Ÿฐ์ฒ˜ exe. ์‹ค์ œ ์Šคํฌ๋ฆฝํŠธ๋Š” "-script"๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ exe์™€ ๊ฐ™์€ ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
์ถ”๊ฐ€๋˜๊ณ  exe๊ฐ€ ๋กœ๋“œํ•˜๊ณ  ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

exe๋Š” ์ง์ ‘ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๊ทธ๋ฆฌ๊ณ  Python ์Šคํฌ๋ฆฝํŠธ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค).
๋‚ด๊ฐ€ ๋ฏฟ๋Š” shebang์€ setuptools๊ฐ€ unices์—์„œ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ
Windows์—์„œ ์ผ๋ฐ˜ Python ์Šคํฌ๋ฆฝํŠธ์— ๋Œ€ํ•ด ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒƒ์€ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
pylauncher๊ฐ€ ์„ค์น˜๋˜์ง€ ์•Š์Œ), ์ž„์˜์˜ Python์œผ๋กœ ์‹œ์ž‘๋˜๋ฏ€๋กœ
๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋Š” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์˜ .py ํŒŒ์ผ์— ์—ฐ๊ฒฐ๋จ
์šฐ๋ฆฌ๊ฐ€ ํ˜„์žฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ํŒŒ์ด์ฌ๋ณด๋‹ค. ๋ฌผ๋ก  ๋‹ค์Œ์—๋„ ๋™์ผํ•˜๊ฒŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.
์šฐ๋ฆฌ๊ฐ€ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ์ž„์˜์˜ Python ์Šคํฌ๋ฆฝํŠธ
์‹คํ–‰ ๊ฐ€๋Šฅ.

pip๋Š” ๋Œ€์‹  distlib๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ์ข…๋ฅ˜์˜ exe ์‹คํ–‰๊ธฐ๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
zip ํŒŒ์ผ์˜ ๋์— ์ถ”๊ฐ€๋œ ์ƒ์„ฑ๋œ ๋Ÿฐ์ฒ˜ ์Šคํฌ๋ฆฝํŠธ
์‹คํ–‰ ๊ฐ€๋Šฅ. ์ด๊ฒƒ์€ __main__.py ์Šคํฌ๋ฆฝํŠธ(A
zipapp) ์‹คํ–‰์„ ์œ„ํ•ด Python์— ์ง์ ‘ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

setuptools์—์„œ ์ด๊ฒƒ์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์€ ์œ ์‚ฌ/๋™์ผํ•œ ์ข…๋ฅ˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค
setuptools์˜ ๋Ÿฐ์ฒ˜. ๊ทธ๋ฆฌ๊ณ  http://xkcd.com/1172/ ์˜ ์ •์‹ ์œผ๋กœ ์ด๊ฒƒ์€
setuptools ์‹คํ–‰๊ธฐ๋ฅผ ์˜ˆ์ƒํ•˜๊ณ  ์‹œ๋„ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๊นจ๋œจ๋ฆด ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
"*-script.py" ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ™•์ธํ•˜์ง€ ์•Š์•˜๋‹ค
์ด๋ฏธ ์ด์— ๋Œ€ํ•œ ๋ฌธ์ œ/ํ™๋ณด๊ฐ€ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€.

Werkzeug๊ฐ€
reloader๋Š” setuptools์˜ ํ˜„์žฌ ์Šคํƒ€์ผ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
๋ฐœ์‚ฌ๊ธฐ. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ์‹ค์ œ๋กœ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค.

ื‘ืชืืจื™ืš 28 ื‘ื ื•ื‘' 2017 20:46, "ewpete" [email protected] ื›ืชื‘:

@androiddrew https://github.com/androiddrew @davidism
https://github.com/davidism ์ด PR์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@segevfiner https://github.com/segevfiner ์ข€ ๋” ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‚˜์š”?
๊ฐ€์žฅ ์ตœ๊ทผ ๋Œ“๊ธ€์— ๋Œ€ํ•œ ์„ธ๋ถ€์ •๋ณด? ์šฐ๋ฆฌ๊ฐ€ ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ œ์•ˆํ•ฉ๋‹ˆ๊นŒ?
Flask๊ฐ€ ์•„๋‹Œ setuptools์—์„œ ๊ทผ๋ณธ ์›์ธ์„ ์ˆ˜์ •ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/pallets/werkzeug/issues/1136#issuecomment-347623921 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AXlg_8OSR3NdbPJzM87dyKPUAA9NpXJ6ks5s7FT7gaJpZM4N5Fcb
.๊ทธ๋งŒํผ

@ewpet ์ œ ์ฒซ PR์ด์—ˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๊ฐœ๋ฐœ ๊ฐ€์ด๋“œ๋ฅผ ๋”ฐ๋ฅด๊ณ  PR์„ ๋ฐฐ์น˜ํ•˜๊ธฐ ์œ„ํ•ด ์ตœ์„ ์„ ๋‹คํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋งŽ์€ ์ง€์นจ์ด ์—†์—ˆ์ง€๋งŒ PR ์˜๊ฒฌ์—์„œ ์ œ์•ˆ๋œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์™„์„ฑ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ๊ทธ๊ฒƒ์ด ํ”„๋กœ์ ํŠธ ํŒ€์˜ ๊ธฐ๋Œ€์— ๋ถ€์‘ํ–ˆ๋Š”์ง€์— ๋Œ€ํ•œ ๋‹ต์„ ๋“ฃ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ดํ›„๋กœ ๊ทธ๊ฒƒ์„ ๋ณธ ์ ์ด ์—†์œผ๋ฉฐ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ๋ฌด์—‡์„ ํ•˜๊ณ  ์‹ถ์–ดํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ์—์„œ ๋งค์šฐ ์ œํ•œ๋œ ์‹œ๊ฐ„์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ์ด๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

@davidism ์‘๋‹ต๋งŒ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๊ณ„์† ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ข‹์€ ์ผ์„ ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

์ด๊ฒƒ์ด ์•„์ง ๋ณ‘ํ•ฉ๋˜์ง€๋Š” ์•Š์•˜์ง€๋งŒ ํ•œ ๊ฐ€์ง€ ๊ฐ€๋Šฅํ•œ ์ž„์‹œ ์ˆ˜์ •์€ _get_args_for_reloading() ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜๊ธฐ ์ „์— ์–ด๋”˜๊ฐ€์— ์›์ˆญ์ด ํŒจ์น˜๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Flask ์Šคํฌ๋ฆฝํŠธ์˜ ๊ฒฝ์šฐ manage.py ํŒŒ์ผ ์‹œ์ž‘ ๋ถ€๋ถ„์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

import werkzeug._reloader
import os, sys

def _get_args_for_reloading():
    rv = [sys.executable]
    py_script = sys.argv[0]
    if os.name == 'nt' and not os.path.exists(py_script) and \
       os.path.exists(py_script + '.exe'):
        py_script += '.exe'
    if os.path.splitext(rv[0])[1] == '.exe' and os.path.splitext(py_script)[1] == '.exe':
        rv.pop()
    rv.append(py_script)
    rv.extend(sys.argv[1:])
    return rv
werkzeug._reloader._get_args_for_reloading = _get_args_for_reloading
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰