Repository: Pylons/pyramid

Issue:
pserve --reload call hupper which call pserve with sys.argv instead of the parameters
If you are calling `pserve.main(argv)` and `argv` contains `--reload` it will call upper with `sys.argv` instead of `argv`.


Discussion:

Resolving patch:
diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py
--- a/pyramid/scripts/pserve.py
+++ b/pyramid/scripts/pserve.py
@@ -35,10 +35,12 @@
 from pyramid.path import AssetResolver
 from pyramid.settings import aslist
 
+
 def main(argv=sys.argv, quiet=False):
     command = PServeCommand(argv, quiet=quiet)
     return command.run()
 
+
 class PServeCommand(object):
 
     description = """\
@@ -113,7 +115,6 @@ class PServeCommand(object):
              "passed here.",
         )
 
-
     ConfigParser = configparser.ConfigParser  # testing
     loadapp = staticmethod(loadapp)  # testing
     loadserver = staticmethod(loadserver)  # testing
@@ -124,9 +125,11 @@ def __init__(self, argv, quiet=False):
         self.args = self.parser.parse_args(argv[1:])
         if quiet:
             self.args.verbose = 0
+        if self.args.reload:
+            self.worker_kwargs = {'argv': argv, "quiet": quiet}
         self.watch_files = []
 
-    def out(self, msg): # pragma: no cover
+    def out(self, msg):  # pragma: no cover
         if self.args.verbose > 0:
             print(msg)
 
@@ -203,6 +206,7 @@ def open_browser():
                 'pyramid.scripts.pserve.main',
                 reload_interval=int(self.args.reload_interval),
                 verbose=self.args.verbose,
+                worker_kwargs=self.worker_kwargs
             )
             return 0
 
@@ -239,8 +243,9 @@ def open_browser():
                 msg = ''
             self.out('Exiting%s (-v to see traceback)' % msg)
 
+
 # For paste.deploy server instantiation (egg:pyramid#wsgiref)
-def wsgiref_server_runner(wsgi_app, global_conf, **kw): # pragma: no cover
+def wsgiref_server_runner(wsgi_app, global_conf, **kw):  # pragma: no cover
     from wsgiref.simple_server import make_server
     host = kw.get('host', '0.0.0.0')
     port = int(kw.get('port', 8080))
@@ -248,13 +253,14 @@ def wsgiref_server_runner(wsgi_app, global_conf, **kw): # pragma: no cover
     print('Starting HTTP server on http://%s:%s' % (host, port))
     server.serve_forever()
 
+
 # For paste.deploy server instantiation (egg:pyramid#cherrypy)
 def cherrypy_server_runner(
         app, global_conf=None, host='127.0.0.1', port=None,
         ssl_pem=None, protocol_version=None, numthreads=None,
         server_name=None, max=None, request_queue_size=None,
         timeout=None
-        ): # pragma: no cover
+        ):  # pragma: no cover
     """
     Entry point for CherryPy's WSGI server
 
@@ -361,5 +367,6 @@ def cherrypy_server_runner(
 
     return server
 
-if __name__ == '__main__': # pragma: no cover
+
+if __name__ == '__main__':  # pragma: no cover
     sys.exit(main() or 0)
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -67,7 +67,7 @@
 testing_extras = tests_require + [
     'nose',
     'coverage',
-    'virtualenv', # for scaffolding tests
+    'virtualenv',  # for scaffolding tests
     ]
 
 setup(name='pyramid',


Test patch:
diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py
--- a/pyramid/tests/test_scripts/test_pserve.py
+++ b/pyramid/tests/test_scripts/test_pserve.py
@@ -2,8 +2,10 @@
 import unittest
 from pyramid.tests.test_scripts import dummy
 
+
 here = os.path.abspath(os.path.dirname(__file__))
 
+
 class TestPServeCommand(unittest.TestCase):
     def setUp(self):
         from pyramid.compat import NativeIO
@@ -48,10 +50,11 @@ def test_parse_vars_good(self):
         inst.loadserver = self._get_server
 
         app = dummy.DummyApp()
+
         def get_app(*args, **kwargs):
             app.global_conf = kwargs.get('global_conf', None)
-        inst.loadapp = get_app
 
+        inst.loadapp = get_app
         inst.run()
         self.assertEqual(app.global_conf, {'a': '1', 'b': '2'})
 
@@ -77,6 +80,36 @@ def test_config_file_finds_watch_files(self):
             os.path.abspath(os.path.join(here, '*.py')),
         ])
 
+    def test_reload_call_hupper_with_correct_args(self):
+        from pyramid.scripts import pserve
+
+        class AttrDict(dict):
+            def __init__(self, *args, **kwargs):
+                super(AttrDict, self).__init__(*args, **kwargs)
+                self.__dict__ = self
+
+        def dummy_start_reloader(*args, **kwargs):
+            dummy_start_reloader.args = args
+            dummy_start_reloader.kwargs = kwargs
+
+        orig_hupper = pserve.hupper
+        try:
+            pserve.hupper = AttrDict(is_active=lambda: False,
+                                     start_reloader=dummy_start_reloader)
+
+            inst = self._makeOne('--reload', 'development.ini')
+            inst.run()
+        finally:
+            pserve.hupper = orig_hupper
+
+        self.assertEquals(dummy_start_reloader.args, ('pyramid.scripts.pserve.main',))
+        self.assertEquals(dummy_start_reloader.kwargs, {
+            'reload_interval': 1,
+            'verbose': 1,
+            'worker_kwargs': {'argv': ['pserve', '--reload', 'development.ini'],
+                              'quiet': False}})
+
+
 class Test_main(unittest.TestCase):
     def _callFUT(self, argv):
         from pyramid.scripts.pserve import main