Repository: frappe/frappe

Issue:
Uninstall-app broken
#### Expected Behaviour
bench uninstall-app {app-name}
app is uninstalled

#### Actual Behaviour
All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue (y/n) ? y
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 94, in <module>
    main()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main
    click.Group(commands=commands)(prog_name='bench')
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/__init__.py", line 25, in _func
    ret = f(frappe._dict(ctx.obj), *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/site.py", line 330, in uninstall
    remove_app(app, dry_run, yes)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/installer.py", line 181, in remove_app
    confirm = input("All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue (y/n) ? ")
  File "<string>", line 1, in <module>
NameError: name 'y' is not defined

#### Steps to reproduce:

1. you have to put the y in quotes like this: 'y'

Frappé version: 



Discussion:
Hi @joshreeder,

I was abled to reproduce the same issue. I guess it is linked to the move to Python 3 and the replacement of `raw_input` with `input`:
https://github.com/frappe/frappe/pull/5017

@achillesrasquinha, sorry to tag you, but since you made the change, is there not supposed to be a support of python 2.7 until the next major version as you wrote in your discuss post ?
https://discuss.erpnext.com/t/erpnext-python-3/33492

If not, I guess we'll have to update to python 3 right now (which is not a bad thing! :smile: )

Thanks!
Thanks for pointing this out! Please feel to assign me these issues. I'll have a compatibility fix sent asap

Resolving patch:
diff --git a/frappe/installer.py b/frappe/installer.py
--- a/frappe/installer.py
+++ b/frappe/installer.py
@@ -6,6 +6,8 @@
 
 from __future__ import unicode_literals, print_function
 
+import six
+
 import os, json, sys, subprocess, shutil
 import frappe
 import frappe.database
@@ -178,7 +180,7 @@ def remove_app(app_name, dry_run=False, yes=False):
 	"""Delete app and all linked to the app's module with the app."""
 
 	if not dry_run and not yes:
-		confirm = input("All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue (y/n) ? ")
+		confirm = six.input("All doctypes (including custom), modules related to this app will be deleted. Are you sure you want to continue (y/n) ? ")
 		if confirm!="y":
 			return
 
@@ -302,7 +304,7 @@ def get_site_config_path():
 
 def get_conf_params(db_name=None, db_password=None):
 	if not db_name:
-		db_name = input("Database Name: ")
+		db_name = six.input("Database Name: ")
 		if not db_name:
 			raise Exception("Database Name Required")
 
diff --git a/frappe/utils/boilerplate.py b/frappe/utils/boilerplate.py
--- a/frappe/utils/boilerplate.py
+++ b/frappe/utils/boilerplate.py
@@ -3,6 +3,8 @@
 
 from __future__ import unicode_literals, print_function
 
+import six
+
 import frappe, os, re
 from frappe.utils import touch_file, encode, cstr
 
@@ -25,7 +27,7 @@ def make_boilerplate(dest, app_name):
 		hook_key = key.split(" (")[0].lower().replace(" ", "_")
 		hook_val = None
 		while not hook_val:
-			hook_val = cstr(input(key + ": "))
+			hook_val = cstr(six.input(key + ": "))
 
 			if not hook_val:
 				defaults = {
diff --git a/frappe/website/render.py b/frappe/website/render.py
--- a/frappe/website/render.py
+++ b/frappe/website/render.py
@@ -111,7 +111,7 @@ def build_response(path, data, http_status_code, headers=None):
 
 	if headers:
 		for key, val in iteritems(headers):
-			response.headers[bytes(key)] = val.encode("utf-8")
+			response.headers[bytes(key.encode("utf-8"))] = val.encode("utf-8")
 
 	return response
 


Test patch: