Hello community, here is the log from the commit of package uwsgi for openSUSE:Factory checked in at 2019-02-11 21:25:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/uwsgi (Old) and /work/SRC/openSUSE:Factory/.uwsgi.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "uwsgi" Mon Feb 11 21:25:24 2019 rev:31 rq:673027 version:2.0.18 Changes: -------- --- /work/SRC/openSUSE:Factory/uwsgi/uwsgi.changes 2018-08-06 11:54:23.685256553 +0200 +++ /work/SRC/openSUSE:Factory/.uwsgi.new.28833/uwsgi.changes 2019-02-11 21:25:31.323076160 +0100 @@ -1,0 +2,18 @@ +Sat Feb 9 16:19:37 UTC 2019 - Michael Ströder <[email protected]> + +- HTTPS URL for source +- update to upstream release 2.0.18 + * Fixed support for Python 3.7 + * Allow to use autoport (socket :0) with custom socket backlog + * pyuwsgi ported to python3 + * pyuwsgi packages fixes + * pyuwsginossl build configuration for building pyuwsgi without ssl support + * Fix unix socket inheritance after reload on FreeBSD + * Fix crashes with --wsgi-env-behavior=holy (#1950) + * Fix invalid free in python plugin (#1942) + * Fix compilation warnings with gcc-8 (#1819) + * Fix spooler python references + * Don't generate build warnings in systemd_logger + * Fix segmentation fault during worker shutdown (#1651) + +------------------------------------------------------------------- Old: ---- uwsgi-2.0.17.1.tar.gz New: ---- uwsgi-2.0.18.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ uwsgi.spec ++++++ --- /var/tmp/diff_new_pack.BYEhMN/_old 2019-02-11 21:25:32.003075793 +0100 +++ /var/tmp/diff_new_pack.BYEhMN/_new 2019-02-11 21:25:32.003075793 +0100 @@ -17,13 +17,13 @@ Name: uwsgi -Version: 2.0.17.1 +Version: 2.0.18 Release: 0 Summary: Application Container Server for Networked/Clustered Web Applications License: Apache-2.0 AND GPL-2.0-only WITH GCC-exception-2.0 Group: Productivity/Networking/Web/Servers Url: https://uwsgi-docs.readthedocs.io/en/latest/ -Source: http://projects.unbit.it/downloads/uwsgi-%{version}.tar.gz +Source: https://projects.unbit.it/downloads/uwsgi-%{version}.tar.gz Source1: opensuse.ini.in Source2: uwsgi.service Source3: django.ini.example ++++++ uwsgi-2.0.17.1.tar.gz -> uwsgi-2.0.18.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/PKG-INFO new/uwsgi-2.0.18/PKG-INFO --- old/uwsgi-2.0.17.1/PKG-INFO 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/PKG-INFO 2019-02-09 15:48:07.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: uWSGI -Version: 2.0.17.1 +Version: 2.0.18 Summary: The uWSGI server Home-page: https://uwsgi-docs.readthedocs.io/en/latest/ Author: Unbit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/buildconf/pyuwsgi.ini new/uwsgi-2.0.18/buildconf/pyuwsgi.ini --- old/uwsgi-2.0.17.1/buildconf/pyuwsgi.ini 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/buildconf/pyuwsgi.ini 2019-02-09 15:48:07.000000000 +0100 @@ -1,5 +1,5 @@ [uwsgi] -main_plugin = pyuwsgi +main_plugin = pyuwsgi,python,gevent,stats_pusher_statsd inherit = base bin_name = pyuwsgi.so as_shared_library = true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/buildconf/pyuwsginossl.ini new/uwsgi-2.0.18/buildconf/pyuwsginossl.ini --- old/uwsgi-2.0.17.1/buildconf/pyuwsginossl.ini 1970-01-01 01:00:00.000000000 +0100 +++ new/uwsgi-2.0.18/buildconf/pyuwsginossl.ini 2019-02-09 15:48:07.000000000 +0100 @@ -0,0 +1,3 @@ +[uwsgi] +inherit = pyuwsgi +ssl = false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/core/emperor.c new/uwsgi-2.0.18/core/emperor.c --- old/uwsgi-2.0.17.1/core/emperor.c 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/core/emperor.c 2019-02-09 15:48:07.000000000 +0100 @@ -153,7 +153,7 @@ } } - strncpy(uebi->id, id, 0xff); + snprintf(uebi->id, 0xff, "%s", id); gettimeofday(&uebi->first_attempt, NULL); memcpy(&uebi->last_attempt, &uebi->first_attempt, sizeof(struct timeval)); uebi->throttle_level = uwsgi.emperor_throttle; @@ -959,7 +959,7 @@ } } -static void uwsgi_emperor_spawn_vassal(struct uwsgi_instance *); +static int uwsgi_emperor_spawn_vassal(struct uwsgi_instance *); int uwsgi_emperor_vassal_start(struct uwsgi_instance *n_ui) { @@ -1105,7 +1105,7 @@ return -1; } -static void uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) { +static int uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) { int i; // run plugin hooks for the vassal @@ -1495,6 +1495,8 @@ } // never here exit(UWSGI_EXILE_CODE); + + return 0; } void uwsgi_imperial_monitor_glob_init(struct uwsgi_emperor_scanner *ues) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/core/master_utils.c new/uwsgi-2.0.18/core/master_utils.c --- old/uwsgi-2.0.17.1/core/master_utils.c 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/core/master_utils.c 2019-02-09 15:48:07.000000000 +0100 @@ -401,7 +401,20 @@ int i; int waitpid_status; - if (uwsgi.new_argv) argv = uwsgi.new_argv; + // hack for removing garbage generated by embedded loaders (like pyuwsgi) + if (uwsgi.new_argc) { + char **tmp_argv = argv; + for(;;) { + char *arg = *tmp_argv; + if (!arg) + break; + if (strlen(arg) == 0) + { + *tmp_argv = NULL; + } + tmp_argv++; + } + } if (!uwsgi.master_is_reforked) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/core/mule.c new/uwsgi-2.0.18/core/mule.c --- old/uwsgi-2.0.17.1/core/mule.c 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/core/mule.c 2019-02-09 15:48:07.000000000 +0100 @@ -452,8 +452,7 @@ mules_list[0] = 0; mules_list++; - strncpy(uwsgi.farms[i].name, farm_value, 0xff); - + snprintf(uwsgi.farms[i].name, 0xff, "%s", farm_value); // create the socket pipe create_signal_pipe(uwsgi.farms[i].signal_pipe); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/core/signal.c new/uwsgi-2.0.18/core/signal.c --- old/uwsgi-2.0.17.1/core/signal.c 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/core/signal.c 2019-02-09 15:48:07.000000000 +0100 @@ -98,6 +98,7 @@ int uwsgi_register_signal(uint8_t sig, char *receiver, void *handler, uint8_t modifier1) { struct uwsgi_signal_entry *use = NULL; + size_t receiver_len; if (!uwsgi.master_process) { uwsgi_log("you cannot register signals without a master\n"); @@ -109,7 +110,8 @@ return -1; } - if (strlen(receiver) > 63) + receiver_len = strlen(receiver); + if (receiver_len > 63) return -1; uwsgi_lock(uwsgi.signal_table_lock); @@ -123,7 +125,7 @@ return -1; } - strncpy(use->receiver, receiver, strlen(receiver) + 1); + strncpy(use->receiver, receiver, receiver_len + 1); use->handler = handler; use->modifier1 = modifier1; use->wid = uwsgi.mywid; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/core/socket.c new/uwsgi-2.0.18/core/socket.c --- old/uwsgi-2.0.17.1/core/socket.c 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/core/socket.c 2019-02-09 15:48:07.000000000 +0100 @@ -1081,6 +1081,7 @@ union uwsgi_sockaddr usa; int abstract = 0; + memset(&usa, 0, sizeof(usa)); socket_type_len = sizeof(struct sockaddr_un); gsa.sa = &usa.sa; if (!getsockname(fd, gsa.sa, &socket_type_len)) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/core/utils.c new/uwsgi-2.0.18/core/utils.c --- old/uwsgi-2.0.17.1/core/utils.c 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/core/utils.c 2019-02-09 15:48:07.000000000 +0100 @@ -1735,16 +1735,19 @@ char *dst = uwsgi_calloc(len); char *ptr = src; + char *dst_ptr = dst; p = strstr(ptr, what); while (p) { - strncat(dst, ptr, (p - ptr)); - strncat(dst, with, with_len); + memcpy(dst_ptr, ptr, p - ptr); + dst_ptr += p - ptr; + memcpy(dst_ptr, with, with_len); + dst_ptr += with_len; ptr = p + wlen; p = strstr(ptr, what); } - strncat(dst, ptr, strlen(ptr)); + snprintf(dst_ptr, strlen(ptr) + 1, "%s", ptr); return dst; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/core/uwsgi.c new/uwsgi-2.0.18/core/uwsgi.c --- old/uwsgi-2.0.17.1/core/uwsgi.c 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/core/uwsgi.c 2019-02-09 15:48:07.000000000 +0100 @@ -28,9 +28,10 @@ #if defined(__APPLE__) && defined(UWSGI_AS_SHARED_LIBRARY) #include <crt_externs.h> -char **environ; +#define UWSGI_ENVIRON (*_NSGetEnviron()) #else extern char **environ; +#define UWSGI_ENVIRON environ #endif UWSGI_DECLARE_EMBEDDED_PLUGINS; @@ -177,7 +178,7 @@ {"connect-and-read", required_argument, 0, "connect to a socket and wait for data from it", uwsgi_opt_connect_and_read, NULL, UWSGI_OPT_IMMEDIATE}, {"extract", required_argument, 0, "fetch/dump any supported address to stdout", uwsgi_opt_extract, NULL, UWSGI_OPT_IMMEDIATE}, - {"listen", required_argument, 'l', "set the socket listen queue size", uwsgi_opt_set_int, &uwsgi.listen_queue, 0}, + {"listen", required_argument, 'l', "set the socket listen queue size", uwsgi_opt_set_int, &uwsgi.listen_queue, UWSGI_OPT_IMMEDIATE}, {"max-vars", required_argument, 'v', "set the amount of internal iovec/vars structures", uwsgi_opt_max_vars, NULL, 0}, {"max-apps", required_argument, 0, "set the maximum number of per-worker applications", uwsgi_opt_set_int, &uwsgi.max_apps, 0}, {"buffer-size", required_argument, 'b', "set internal buffer size", uwsgi_opt_set_16bit, &uwsgi.buffer_size, 0}, @@ -1740,7 +1741,7 @@ uwsgi.orig_argv = argv; uwsgi.argv = argv; uwsgi.argc = argc; - uwsgi.environ = environ; + uwsgi.environ = UWSGI_ENVIRON; // avoid messing with fake environ if (envp && *environ != *envp) return; @@ -2057,13 +2058,6 @@ } void uwsgi_setup(int argc, char *argv[], char *envp[]) { -#ifdef UWSGI_AS_SHARED_LIBRARY -#ifdef __APPLE__ - char ***envPtr = _NSGetEnviron(); - environ = *envPtr; -#endif -#endif - int i; struct utsname uuts; @@ -2106,8 +2100,6 @@ atexit(vacuum); // call user scripts atexit(uwsgi_exec_atexit); - // call plugin specific exit hooks - atexit(uwsgi_plugins_atexit); #ifdef UWSGI_SSL // call legions death hooks atexit(uwsgi_legion_atexit); @@ -2193,7 +2185,7 @@ uwsgi.response_header_limit = UMAX16; // ok we can now safely play with argv and environ - fixup_argv_and_environ(argc, argv, environ, envp); + fixup_argv_and_environ(argc, argv, UWSGI_ENVIRON, envp); if (gethostname(uwsgi.hostname, 255)) { uwsgi_error("gethostname()"); @@ -2247,7 +2239,7 @@ build_options(); #endif //parse environ - parse_sys_envs(environ); + parse_sys_envs(UWSGI_ENVIRON); // parse commandline options uwsgi_commandline_config(); @@ -3120,6 +3112,11 @@ uwsgi_init_all_apps(); } + // Register uwsgi atexit plugin callbacks after all applications have + // been loaded. This ensures plugin atexit callbacks are called prior + // to application registered atexit callbacks. + atexit(uwsgi_plugins_atexit); + if (!uwsgi.master_as_root) { uwsgi_as_root(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/plugins/python/python_plugin.c new/uwsgi-2.0.18/plugins/python/python_plugin.c --- old/uwsgi-2.0.17.1/plugins/python/python_plugin.c 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/plugins/python/python_plugin.c 2019-02-09 15:48:07.000000000 +0100 @@ -971,20 +971,20 @@ char *uwsgi_pythonize(char *orig) { - char *name = uwsgi_concat2(orig, ""); - size_t i; - size_t len = 0; + char *name; + size_t i, len, offset = 0; - if (!strncmp(name, "sym://", 6)) { - name+=6; + if (!strncmp(orig, "sym://", 6)) { + offset = 6; } - else if (!strncmp(name, "http://", 7)) { - name+=7; + else if (!strncmp(orig, "http://", 7)) { + offset = 7; } - else if (!strncmp(name, "data://", 7)) { - name+=7; + else if (!strncmp(orig, "data://", 7)) { + offset = 7; } + name = uwsgi_concat2(orig+offset, ""); len = strlen(name); for(i=0;i<len;i++) { if (name[i] == '.') { @@ -1069,8 +1069,11 @@ // to equalise the refcount of the environ PyDict_DelItemString(up.embedded_dict, "env"); } + // avoid to decref environ if it is mapped to the python callable + if (PyTuple_GetItem(wsgi_req->async_args, 0) != wsgi_req->async_environ) { + Py_DECREF((PyObject *)wsgi_req->async_environ); + } Py_DECREF((PyObject *) wsgi_req->async_args); - Py_DECREF((PyObject *)wsgi_req->async_environ); } @@ -1092,15 +1095,21 @@ exit(1); } - if (!up.wsgi_env_behaviour) { - up.wsgi_env_create = uwsgi_python_create_env_cheat; - up.wsgi_env_destroy = uwsgi_python_destroy_env_cheat; - } - else if (!strcmp(up.wsgi_env_behaviour, "holy")) { - up.wsgi_env_create = uwsgi_python_create_env_holy; - up.wsgi_env_destroy = uwsgi_python_destroy_env_holy; + if (up.wsgi_env_behaviour) { + if (!strcmp(up.wsgi_env_behaviour, "holy")) { + up.wsgi_env_create = uwsgi_python_create_env_holy; + up.wsgi_env_destroy = uwsgi_python_destroy_env_holy; + } + else if (!strcmp(up.wsgi_env_behaviour, "cheat")) { + up.wsgi_env_create = uwsgi_python_create_env_cheat; + up.wsgi_env_destroy = uwsgi_python_destroy_env_cheat; + } + else { + uwsgi_log("invalid wsgi-env-behaviour value: %s\n", up.wsgi_env_behaviour); + exit(1); + } } - else if (!strcmp(up.wsgi_env_behaviour, "cheat")) { + else { up.wsgi_env_create = uwsgi_python_create_env_cheat; up.wsgi_env_destroy = uwsgi_python_destroy_env_cheat; } @@ -1481,6 +1490,7 @@ if (!PyObject_HasAttrString(mod, "__file__")) continue; PyObject *mod_file = PyObject_GetAttrString(mod, "__file__"); if (!mod_file) continue; + if (mod_file == Py_None) continue; #ifdef PYTHREE PyObject *zero = PyUnicode_AsUTF8String(mod_file); char *mod_filename = PyString_AsString(zero); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/plugins/python/uwsgi_pymodule.c new/uwsgi-2.0.18/plugins/python/uwsgi_pymodule.c --- old/uwsgi-2.0.17.1/plugins/python/uwsgi_pymodule.c 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/plugins/python/uwsgi_pymodule.c 2019-02-09 15:48:07.000000000 +0100 @@ -148,13 +148,11 @@ if (!PyTuple_Check(zero)) { uwsgi_log("invalid python dictionary item\n"); - Py_DECREF(zero); continue; } if (PyTuple_Size(zero) < 2) { uwsgi_log("invalid python dictionary item\n"); - Py_DECREF(zero); continue; } key = PyTuple_GetItem(zero, 0); @@ -167,7 +165,6 @@ } if (!PyString_Check(key) || !PyString_Check(val)) { - Py_DECREF(zero); continue; } @@ -187,8 +184,6 @@ bufptr += valsize; } - Py_DECREF(zero); - } return buf; @@ -1986,7 +1981,6 @@ if (PyString_Check(val)) { valsize = PyString_Size(val); if (uwsgi_buffer_append_keyval(ub, PyString_AsString(key), keysize, PyString_AsString(val), valsize)) { - Py_DECREF(zero); uwsgi_buffer_destroy(ub); goto error; } @@ -1998,31 +1992,26 @@ PyObject *str = PyObject_Str(val); #endif if (!str) { - Py_DECREF(zero); uwsgi_buffer_destroy(ub); goto error; } if (uwsgi_buffer_append_keyval(ub, PyString_AsString(key), keysize, PyString_AsString(str), PyString_Size(str))) { - Py_DECREF(zero); Py_DECREF(str); - uwsgi_buffer_destroy(ub); - goto error; - } + uwsgi_buffer_destroy(ub); + goto error; + } Py_DECREF(str); } } else { - Py_DECREF(zero); uwsgi_buffer_destroy(ub); goto error; } } else { - Py_DECREF(zero); uwsgi_buffer_destroy(ub); goto error; } - Py_DECREF(zero); } else { uwsgi_buffer_destroy(ub); @@ -2041,7 +2030,9 @@ if (pybody) { - Py_DECREF(pybody); + if (PyString_Check(pybody)) { + Py_DECREF(pybody); + } } Py_DECREF(spool_vars); @@ -2177,9 +2168,6 @@ } apps_tuple = PyDict_GetItemString(worker_dict, "apps"); - if (apps_tuple) { - Py_DECREF(apps_tuple); - } PyDict_Clear(worker_dict); @@ -2560,11 +2548,11 @@ static PyMethodDef uwsgi_spooler_methods[] = { #ifdef PYTHREE - {"send_to_spooler", (PyCFunction) py_uwsgi_send_spool, METH_VARARGS | METH_KEYWORDS, ""}, - {"spool", (PyCFunction) py_uwsgi_send_spool, METH_VARARGS | METH_KEYWORDS, ""}, + {"send_to_spooler", (PyCFunction)(void *)py_uwsgi_send_spool, METH_VARARGS|METH_KEYWORDS, ""}, + {"spool", (PyCFunction)(void *)py_uwsgi_send_spool, METH_VARARGS|METH_KEYWORDS, ""}, #else - {"send_to_spooler", (PyCFunction) py_uwsgi_send_spool, METH_KEYWORDS, ""}, - {"spool", (PyCFunction) py_uwsgi_send_spool, METH_KEYWORDS, ""}, + {"send_to_spooler", (PyCFunction)(void *)py_uwsgi_send_spool, METH_KEYWORDS, ""}, + {"spool", (PyCFunction)(void *)py_uwsgi_send_spool, METH_KEYWORDS, ""}, #endif {"set_spooler_frequency", py_uwsgi_spooler_freq, METH_VARARGS, ""}, {"spooler_jobs", py_uwsgi_spooler_jobs, METH_VARARGS, ""}, @@ -2662,7 +2650,7 @@ {"mule_msg", py_uwsgi_mule_msg, METH_VARARGS, ""}, {"farm_msg", py_uwsgi_farm_msg, METH_VARARGS, ""}, - {"mule_get_msg", (PyCFunction) py_uwsgi_mule_get_msg, METH_VARARGS|METH_KEYWORDS, ""}, + {"mule_get_msg", (PyCFunction)(void *)py_uwsgi_mule_get_msg, METH_VARARGS|METH_KEYWORDS, ""}, {"farm_get_msg", py_uwsgi_farm_get_msg, METH_VARARGS, ""}, {"in_farm", py_uwsgi_in_farm, METH_VARARGS, ""}, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/plugins/pyuwsgi/pyuwsgi.c new/uwsgi-2.0.18/plugins/pyuwsgi/pyuwsgi.c --- old/uwsgi-2.0.17.1/plugins/pyuwsgi/pyuwsgi.c 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/plugins/pyuwsgi/pyuwsgi.c 2019-02-09 15:48:07.000000000 +0100 @@ -1,7 +1,11 @@ #include "../python/uwsgi_python.h" //FIXME: [upstream:python] needs PyAPI_FUNC(void) +#ifdef PYTHREE +extern void Py_GetArgcArgv(int *, wchar_t ***); +#else extern void Py_GetArgcArgv(int *, char ***); +#endif extern struct uwsgi_server uwsgi; extern struct uwsgi_python up; @@ -15,311 +19,342 @@ static char *new_argv_buf = NULL; -PyObject * -pyuwsgi_setup(PyObject *self, PyObject *args, PyObject *kwds) -{ - if (new_argv) { - PyErr_SetString( - PyExc_RuntimeError, - "uWSGI already setup" - ); - return NULL; - } - - if (uwsgi.mywid) { - PyErr_SetString( - PyExc_RuntimeError, - "uWSGI must be setup by master" - ); - return NULL; - } - - PyObject *iterator; - - if (args == NULL || PyObject_Size(args) == 0) { - PyObject *argv = PySys_GetObject("argv"); - if (argv == NULL) - return NULL; - - // during site.py maybe - if (argv == Py_None) { - argv = PyTuple_New(0); - iterator = PyObject_GetIter(argv); - Py_DECREF(argv); - } - else { - iterator = PyObject_GetIter(argv); - if (PyObject_Size(argv) > 0) { - // forward past argv0 - PyObject *item = PyIter_Next(iterator); - Py_DECREF(item); - } - } - } - else if ( - PyObject_Size(args) == 1 - && !PyString_Check(PyTuple_GetItem(args, 0)) - ) { - iterator = PyObject_GetIter(PyTuple_GetItem(args, 0)); - } - else { - iterator = PyObject_GetIter(args); - } - - if (iterator == NULL) { - return NULL; - } - - size_t size = 1; - //FIXME: ARGS prior to and including -c/-m are REQUIRED! - PyObject *item = PyString_FromString(orig_argv[0]); - PyObject *args_li = PyList_New(0); - PyList_Append(args_li, item); - size += strlen(orig_argv[0]) + 1; - Py_DECREF(item); - - while ((item = PyIter_Next(iterator))) { - //TODO: call str(...) on everything - PyList_Append(args_li, item); - size += PyObject_Length(item) + 1; - Py_DECREF(item); - } - - Py_DECREF(iterator); - - new_argc = PyObject_Length(args_li); - new_argv = uwsgi_calloc(sizeof(char *) * (new_argc + 1)); - new_argv_buf = uwsgi_calloc(size); - - int i = 0; - char *new_argv_ptr = new_argv_buf; - for(i=0; i < new_argc; i++) { - PyObject *arg = PyList_GetItem(args_li, i); - char *arg_str = PyString_AsString(arg); - new_argv[i] = new_argv_ptr; - strcpy(new_argv_ptr, arg_str); - new_argv_ptr += strlen(arg_str) + 1; - } - - PyObject *args_tup = PyList_AsTuple(args_li); - PyObject_SetAttrString(self, "NEW_ARGV", args_tup); - Py_DECREF(args_tup); - Py_DECREF(args_li); - - // TODO: convention here is a goto methinks? - if (PyErr_Occurred()) { - free(new_argv_buf); - free(new_argv); - new_argv = 0; - new_argc = 0; - return NULL; - } - - //TODO: ...??? - // actually do the thing! - PyThreadState *_tstate = PyThreadState_Get(); - uwsgi_setup(orig_argc, orig_argv, environ); - PyThreadState_Swap(_tstate); +PyObject *pyuwsgi_setup(PyObject * self, PyObject * args, PyObject * kwds) { - Py_INCREF(self); - return self; + if (new_argv) { + PyErr_SetString(PyExc_RuntimeError, "uWSGI already setup"); + return NULL; + } + + if (uwsgi.mywid) { + PyErr_SetString(PyExc_RuntimeError, "uWSGI must be setup by master"); + return NULL; + } + + PyObject *iterator; + + if (args == NULL || PyObject_Size(args) == 0) { + PyObject *argv = PySys_GetObject("argv"); + if (argv == NULL) + return NULL; + + // during site.py maybe + if (argv == Py_None) { + argv = PyTuple_New(0); + iterator = PyObject_GetIter(argv); + Py_DECREF(argv); + } + else { + iterator = PyObject_GetIter(argv); + if (PyObject_Size(argv) > 0) { + // forward past argv0 + PyObject *item = PyIter_Next(iterator); + Py_DECREF(item); + } + } + } + else if (PyObject_Size(args) == 1 && !PyString_Check(PyTuple_GetItem(args, 0)) + ) { + iterator = PyObject_GetIter(PyTuple_GetItem(args, 0)); + } + else { + iterator = PyObject_GetIter(args); + } + + if (iterator == NULL) { + return NULL; + } + + size_t size = 1; + //FIXME: ARGS prior to and including -c/-m are REQUIRED! +#ifdef PYTHREE + PyObject *item = PyUnicode_FromString(orig_argv[0]); +#else + PyObject *item = PyString_FromString(orig_argv[0]); +#endif + PyObject *args_li = PyList_New(0); + PyList_Append(args_li, item); + size += strlen(orig_argv[0]) + 1; + Py_DECREF(item); + + + while ((item = PyIter_Next(iterator))) { + PyObject *py_str = PyObject_Str(item); + PyList_Append(args_li, py_str); +#ifdef PYTHREE + char *str = PyUnicode_AsUTF8(py_str); + size += strlen(str) + 1; +#else + size += PyObject_Length(item) + 1; +#endif + Py_DECREF(item); + Py_DECREF(py_str); + } + + Py_DECREF(iterator); + + new_argc = PyObject_Length(args_li); + new_argv = uwsgi_calloc(sizeof(char *) * (new_argc + 2)); + new_argv_buf = uwsgi_calloc(size); + + int i = 0; + char *new_argv_ptr = new_argv_buf; + for (i = 0; i < new_argc; i++) { + PyObject *arg = PyList_GetItem(args_li, i); +#ifdef PYTHREE + char *arg_str = PyUnicode_AsUTF8(arg); +#else + char *arg_str = PyString_AsString(arg); +#endif + new_argv[i] = new_argv_ptr; + strcpy(new_argv_ptr, arg_str); + new_argv_ptr += strlen(arg_str) + 1; + } + + PyObject *args_tup = PyList_AsTuple(args_li); + PyObject_SetAttrString(self, "NEW_ARGV", args_tup); + Py_DECREF(args_tup); + Py_DECREF(args_li); + + + // TODO: convention here is a goto methinks? + if (PyErr_Occurred()) { + free(new_argv_buf); + free(new_argv); + new_argv = 0; + new_argc = 0; + return NULL; + } + + + //TODO: ...??? + // actually do the thing! + PyThreadState *_tstate = PyThreadState_Get(); + uwsgi_setup(orig_argc, orig_argv, environ); + PyThreadState_Swap(_tstate); + + Py_INCREF(self); + return self; } -PyObject * -pyuwsgi_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - if (pyuwsgi_setup(self, args, kwds) == NULL) { - return NULL; - } +PyObject *pyuwsgi_init(PyObject * self, PyObject * args, PyObject * kwds) { + if (pyuwsgi_setup(self, args, kwds) == NULL) { + return NULL; + } - int rc = uwsgi_run(); + int rc = uwsgi_run(); - // never(?) here - return Py_BuildValue("i", rc); + // never(?) here + return Py_BuildValue("i", rc); } -PyObject * -pyuwsgi_run(PyObject *self, PyObject *args, PyObject *kwds) -{ - // backcompat - if (new_argv == NULL && - pyuwsgi_setup(self, args, kwds) == NULL) { - return NULL; - } +PyObject *pyuwsgi_run(PyObject * self, PyObject * args, PyObject * kwds) { + // backcompat + if (new_argv == NULL && pyuwsgi_setup(self, args, kwds) == NULL) { + return NULL; + } - int rc = uwsgi_run(); + int rc = uwsgi_run(); - // never(?) here - return Py_BuildValue("i", rc); + // never(?) here + return Py_BuildValue("i", rc); } PyMethodDef methods[] = { - {"run", - (PyCFunction) pyuwsgi_run, - METH_VARARGS | METH_KEYWORDS, - "run(...)" - "\n>>> 0" - "\n" - "\n * Call setup(...) if not configured" - "\n * Begin uWSGI mainloop" - "\n NOTE: will not return" - "\n" - }, - {"init", - (PyCFunction) pyuwsgi_init, - METH_VARARGS | METH_KEYWORDS, - "init(...)" - "\n>>> 0" - "\n" - "\n * Call setup(...)" - "\n * Begin uWSGI mainloop" - "\n NOTE: will not return" - "\n" - }, - {"setup", - (PyCFunction) pyuwsgi_setup, - METH_VARARGS | METH_KEYWORDS, - "setup('--master', ...)" - "\n>>> <module 'uwsgi' from \"uwsgi.so\">" - "\n" - "\n * Initialize uWSGI core with (...)" - "\n MUST only call once [RuntimeException]" - "\n MUST only call from master [RuntimeException]" - "\n" - }, - {NULL, NULL, 0, NULL} + {"run", + (PyCFunction) pyuwsgi_run, + METH_VARARGS | METH_KEYWORDS, + "run(...)" "\n>>> 0" "\n" "\n * Call setup(...) if not configured" "\n * Begin uWSGI mainloop" "\n NOTE: will not return" "\n"} + , + {"init", + (PyCFunction) pyuwsgi_init, + METH_VARARGS | METH_KEYWORDS, + "init(...)" "\n>>> 0" "\n" "\n * Call setup(...)" "\n * Begin uWSGI mainloop" "\n NOTE: will not return" "\n"} + , + {"setup", + (PyCFunction) pyuwsgi_setup, + METH_VARARGS | METH_KEYWORDS, + "setup('--master', ...)" "\n>>> <module 'uwsgi' from \"uwsgi.so\">" "\n" "\n * Initialize uWSGI core with (...)" "\n MUST only call once [RuntimeException]" "\n MUST only call from master [RuntimeException]" "\n"} + , + {NULL, NULL, 0, NULL} }; -static void -pyuwsgi_set_orig_argv(PyObject *self) -{ - - // ask python for the original argc/argv saved in Py_Main() - Py_GetArgcArgv(&orig_argc, &orig_argv); - - // [re?]export to uwsgi.orig_argv - PyObject *m_orig_argv; - m_orig_argv = PyTuple_New(orig_argc); - - int i = 0; - int i_cm = -1; - - for(i=0; i < orig_argc; i++) { - char *arg = orig_argv[i]; - //XXX: _PyOS_optarg != 0 also indicates python quit early... - //FIXME: [upstream:python] orig_argv could be mangled; reset - // rel: http://bugs.python.org/issue8202 - orig_argv[i + 1] = arg + strlen(arg) + 1; - - // look for -c or -m and record the offset - if (i_cm < 0) { - if (strcmp(arg, "-c") || strcmp(arg, "-m")) { - // python's getopt would've failed had + 1 not exist - i_cm = i + 1; - } - else if (!uwsgi_startswith(arg, "-c", 2) || - !uwsgi_startswith(arg, "-m", 2)) { - //FIXME: ARGS prior to and including -c/-m are REQUIRED, - // but NOT a part of the uWSGI argv! Needed to make - // exec*() self-referential: exec*(...) -> uwsgi - // - // want: uwsgi.binary_argv[:] + uwsgi.argv[:]! - // binary_argv = [binary_path] + args - i_cm = i; - } - } - - PyTuple_SetItem(m_orig_argv, i, PyString_FromString(arg)); - } - - //TODO: howto properly detect uwsgi already running... - // orig_argv == uwsgi.orig_argv (?) - // ^^^ but if Py_Main not called, python/main.c:orig_argv unset - // howto interact/detect things in general - PyObject *m_new_argv = PyTuple_New(0); - PyObject_SetAttrString(self, "NEW_ARGV", m_new_argv); - PyObject_SetAttrString(self, "ORIG_ARGV", m_orig_argv); - Py_DECREF(m_new_argv); - Py_DECREF(m_orig_argv); +static void pyuwsgi_set_orig_argv(PyObject * self) { + + // ask python for the original argc/argv saved in Py_Main() +#ifdef PYTHREE + wchar_t ** tmp_orig_argv = NULL; + Py_GetArgcArgv(&orig_argc, &tmp_orig_argv); + int j; + orig_argv = uwsgi_calloc(sizeof(char *) * (orig_argc + 2)); + size_t size = 0; + for (j=0;j<orig_argc;j++) { + size += (wcslen(tmp_orig_argv[j]) + 1) * sizeof(wchar_t); + } + // add environment to size + char **env = environ; + while(*env) { + size += strlen(*env) + 1; + env++; + } + // this contguous memory will remain allocated for the whole process lifetime + // TODO we need a trick for setproctitle() to get access to the original argv[0] + // check https://github.com/dvarrazzo/py-setproctitle/blob/master/src/spt_setup.c#L151 + char *data = uwsgi_calloc(size); + for (j=0;j<orig_argc;j++) { + size_t strsize = (wcslen(tmp_orig_argv[j]) + 1) * sizeof(wchar_t); + orig_argv[j] = data; + wcstombs(orig_argv[j], tmp_orig_argv[j], strsize); + data += strlen(orig_argv[j]) + 1; + } + +#else + Py_GetArgcArgv(&orig_argc, &orig_argv); +#endif + + // [re?]export to uwsgi.orig_argv + PyObject *m_orig_argv; + m_orig_argv = PyTuple_New(orig_argc); + + int i = 0; + int i_cm = -1; + + for (i = 0; i < orig_argc; i++) { + char *arg = orig_argv[i]; + //XXX: _PyOS_optarg != 0 also indicates python quit early... + //FIXME: [upstream:python] orig_argv could be mangled; reset + // rel: http://bugs.python.org/issue8202 + orig_argv[i + 1] = arg + strlen(arg) + 1; + + // look for -c or -m and record the offset + if (i_cm < 0) { + if (strcmp(arg, "-c") || strcmp(arg, "-m")) { + // python's getopt would've failed had + 1 not exist + i_cm = i + 1; + } + else if (!uwsgi_startswith(arg, "-c", 2) || !uwsgi_startswith(arg, "-m", 2)) { + //FIXME: ARGS prior to and including -c/-m are REQUIRED, + // but NOT a part of the uWSGI argv! Needed to make + // exec*() self-referential: exec*(...) -> uwsgi + // + // want: uwsgi.binary_argv[:] + uwsgi.argv[:]! + // binary_argv = [binary_path] + args + i_cm = i; + } + } + +#ifdef PYTHREE + PyTuple_SetItem(m_orig_argv, i, PyUnicode_FromString(arg)); +#else + PyTuple_SetItem(m_orig_argv, i, PyString_FromString(arg)); +#endif + } + + //TODO: howto properly detect uwsgi already running... + // orig_argv == uwsgi.orig_argv (?) + // ^^^ but if Py_Main not called, python/main.c:orig_argv unset + // howto interact/detect things in general + PyObject *m_new_argv = PyTuple_New(0); + PyObject_SetAttrString(self, "NEW_ARGV", m_new_argv); + PyObject_SetAttrString(self, "ORIG_ARGV", m_orig_argv); + Py_DECREF(m_new_argv); + Py_DECREF(m_orig_argv); } -static PyObject * -pyuwsgi_init_as(char *mod_name) -{ - - PyObject *m; - - m = PyImport_GetModuleDict(); - if (m == NULL) { - return NULL; - } - - m = PyDict_GetItemString(m, mod_name); - if (!m) { - m = Py_InitModule(mod_name, NULL); - } - - if (orig_argc < 0) { - pyuwsgi_set_orig_argv(m); - } - - int i; - for (i=0; methods[i].ml_name != NULL; i++) { - PyObject *fun = PyObject_GetAttrString(m, methods[i].ml_name); - if (fun != NULL) { - // already exists - Py_DECREF(fun); - continue; - } - - PyErr_Clear(); - - // rel: Python/modsupport.c:Py_InitModule4 - PyObject* name = PyString_FromString(methods[i].ml_name); - // fun(self, ...) - fun = PyCFunction_NewEx(&methods[i], m, name); - Py_DECREF(name); - // module.fun - PyObject_SetAttrString(m, methods[i].ml_name, fun); - Py_DECREF(fun); - } +#ifdef PYTHREE +static struct PyModuleDef pyuwsgi_module = { + PyModuleDef_HEAD_INIT, + "pyuwsgi", /* name of module */ + NULL, /* module documentation, may be NULL */ + -1, /* size of per-interpreter state of the + * module, or -1 if the module keeps state in + * global variables. */ + methods +}; +#endif + + +#ifndef PYTHREE +static PyObject *pyuwsgi_init_as(char *mod_name) { + + PyObject *m; - return m; + m = PyImport_GetModuleDict(); + if (m == NULL) { + return NULL; + } + + m = PyDict_GetItemString(m, mod_name); + if (!m) { + m = Py_InitModule(mod_name, NULL); + } + + if (orig_argc < 0) { + pyuwsgi_set_orig_argv(m); + } + + int i; + for (i = 0; methods[i].ml_name != NULL; i++) { + PyObject *fun = PyObject_GetAttrString(m, methods[i].ml_name); + if (fun != NULL) { + // already exists + Py_DECREF(fun); + continue; + } + + PyErr_Clear(); + + // rel: Python/modsupport.c:Py_InitModule4 + PyObject *name = PyString_FromString(methods[i].ml_name); + // fun(self, ...) + fun = PyCFunction_NewEx(&methods[i], m, name); + Py_DECREF(name); + // module.fun + PyObject_SetAttrString(m, methods[i].ml_name, fun); + Py_DECREF(fun); + } + + return m; } +#endif -PyMODINIT_FUNC -initpyuwsgi() -{ - (void) pyuwsgi_init_as("pyuwsgi"); +#ifdef PYTHREE +PyMODINIT_FUNC PyInit_pyuwsgi() { + PyObject *m = PyModule_Create(&pyuwsgi_module); + if (orig_argc < 0) { + pyuwsgi_set_orig_argv(m); + } + return m; +} +#else +PyMODINIT_FUNC initpyuwsgi() { + (void) pyuwsgi_init_as("pyuwsgi"); } // allow the module to be called `uwsgi` -PyMODINIT_FUNC -inituwsgi() -{ - (void) pyuwsgi_init_as("uwsgi"); +PyMODINIT_FUNC inituwsgi() { + (void) pyuwsgi_init_as("uwsgi"); } +#endif -void pyuwsgi_load() -{ - if (new_argc > -1) { - uwsgi.new_argc = new_argc; - uwsgi.new_argv = new_argv; - } +void pyuwsgi_load() { + if (new_argc > -1) { + uwsgi.new_argc = new_argc; + uwsgi.new_argv = new_argv; + } } struct uwsgi_plugin pyuwsgi_plugin = { - .name = "pyuwsgi", - .on_load = pyuwsgi_load, + .name = "pyuwsgi", + .on_load = pyuwsgi_load, }; - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/plugins/pyuwsgi/uwsgiplugin.py new/uwsgi-2.0.18/plugins/pyuwsgi/uwsgiplugin.py --- old/uwsgi-2.0.17.1/plugins/pyuwsgi/uwsgiplugin.py 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/plugins/pyuwsgi/uwsgiplugin.py 2019-02-09 15:48:07.000000000 +0100 @@ -1,5 +1,5 @@ from distutils import sysconfig -import os, sys +import os os.environ['UWSGI_PYTHON_NOLIB'] = '1' @@ -8,8 +8,4 @@ LDFLAGS = [] LIBS = [] -PY3 = sys.version_info[0] >= 3 -if not PY3: - GCC_LIST = ['pyuwsgi'] -else: - GCC_LIST = [] +GCC_LIST = ['pyuwsgi'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/plugins/systemd_logger/uwsgiplugin.py new/uwsgi-2.0.18/plugins/systemd_logger/uwsgiplugin.py --- old/uwsgi-2.0.17.1/plugins/systemd_logger/uwsgiplugin.py 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/plugins/systemd_logger/uwsgiplugin.py 2019-02-09 15:48:07.000000000 +0100 @@ -2,9 +2,13 @@ NAME = 'systemd_logger' -CFLAGS = os.popen('pkg-config --cflags libsystemd-journal').read().rstrip().split() -CFLAGS += os.popen('pkg-config --cflags libsystemd').read().rstrip().split() +if os.popen('pkg-config --exists libsystemd-journal').close() is None: + CFLAGS = os.popen('pkg-config --cflags libsystemd-journal').read().rstrip().split() + LIBS = os.popen('pkg-config --libs libsystemd-journal').read().rstrip().split() +else: + CFLAGS = os.popen('pkg-config --cflags libsystemd').read().rstrip().split() + LIBS = os.popen('pkg-config --libs libsystemd').read().rstrip().split() + LDFLAGS = [] -LIBS = os.popen('pkg-config --libs libsystemd-journal').read().rstrip().split() -LIBS += os.popen('pkg-config --libs libsystemd').read().rstrip().split() + GCC_LIST = ['systemd_logger'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/setup.pyuwsgi.py new/uwsgi-2.0.18/setup.pyuwsgi.py --- old/uwsgi-2.0.17.1/setup.pyuwsgi.py 1970-01-01 01:00:00.000000000 +0100 +++ new/uwsgi-2.0.18/setup.pyuwsgi.py 2019-02-09 15:48:07.000000000 +0100 @@ -0,0 +1,180 @@ +# encoding: utf-8 + +""" +This is a hack allowing you installing +uWSGI and uwsgidecorators via pip and easy_install +since 1.9.11 it automatically detects pypy +""" + +import os +import sys +import errno +import shlex +import uwsgiconfig + +from setuptools import setup +from setuptools.command.build_ext import build_ext +from distutils.core import Extension + + +class uWSGIBuildExt(build_ext): + + UWSGI_NAME = 'pyuwsgi' + UWSGI_PLUGIN = 'pyuwsgi' + UWSGI_PROFILE = 'pyuwsgi' + + def build_extensions(self): + self.uwsgi_setup() + # XXX: needs uwsgiconfig fix + self.uwsgi_build() + if 'UWSGI_USE_DISTUTILS' not in os.environ: + # XXX: needs uwsgiconfig fix + # uwsgiconfig.build_uwsgi(self.uwsgi_config) + return + + else: + # XXX: needs uwsgiconfig fix + os.unlink(self.uwsgi_config.get('bin_name')) + + # FIXME: else build fails :( + for baddie in set(self.compiler.compiler_so) & set(('-Wstrict-prototypes',)): + self.compiler.compiler_so.remove(baddie) + + build_ext.build_extensions(self) + + def uwsgi_setup(self): + profile = os.environ.get('UWSGI_PROFILE') or 'buildconf/%s.ini' % self.UWSGI_PROFILE + + if not profile.endswith('.ini'): + profile = profile + '.ini' + if '/' not in profile: + profile = 'buildconf/' + profile + + # FIXME: update uwsgiconfig to properly set _EVERYTHING_! + config = uwsgiconfig.uConf(profile) + # insert in the beginning so UWSGI_PYTHON_NOLIB is exported + # before the python plugin compiles + ep = config.get('embedded_plugins').split(',') + if self.UWSGI_PLUGIN in ep: + ep.remove(self.UWSGI_PLUGIN) + ep.insert(0, self.UWSGI_PLUGIN) + config.set('embedded_plugins', ','.join(ep)) + config.set('as_shared_library', 'true') + config.set('bin_name', self.get_ext_fullpath(self.UWSGI_NAME)) + try: + os.makedirs(os.path.dirname(config.get('bin_name'))) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + self.uwsgi_profile = profile + self.uwsgi_config = config + + def uwsgi_build(self): + uwsgiconfig.build_uwsgi(self.uwsgi_config) + + # XXX: merge uwsgi_setup (see other comments) + for ext in self.extensions: + if ext.name == self.UWSGI_NAME: + ext.sources = [s + '.c' for s in self.uwsgi_config.gcc_list] + ext.library_dirs = self.uwsgi_config.include_path[:] + ext.libraries = list() + ext.extra_compile_args = list() + + for x in uwsgiconfig.uniq_warnings( + self.uwsgi_config.ldflags + self.uwsgi_config.libs, + ): + for y in shlex.split(x): + if y.startswith('-l'): + ext.libraries.append(y[2:]) + elif y.startswith('-L'): + ext.library_dirs.append(y[2:]) + + for x in self.uwsgi_config.cflags: + for y in shlex.split(x): + if y: + ext.extra_compile_args.append(y) + + +LONG_DESCRIPTION = """ +# The uWSGI server as a Python module + +## Install + +``` +pip install pyuwsgi +``` + +## Run + +The installed script, `pyuwsgi`, is a drop-in replacement for the `uwsgi` script. + +You can also call it directly in your Python code with a list of valid uWSGI options: + +```python +import pyuwsgi +pyuwsgi.run(["--help"]) +``` + +## Differences from uWSGI + +This is built from uWSGI's source without any modifications. +A different [`setup.py`](https://github.com/unbit/uwsgi/blob/uwsgi-2.0/setup.pyuwsgi.py) +is used to make the project a friendlier part of the Python ecosystem. It allows it +to be imported as a Python module and distributed using the +[wheel format](https://www.python.org/dev/peps/pep-0427/). + +The full uWSGI documentation can be found at +[https://uwsgi-docs.readthedocs.org](https://uwsgi-docs.readthedocs.org). + +--- + +[](https://lincolnloop.com) + +`pyuwsgi` is sponsored by [Lincoln Loop](https://lincolnloop.com). + +[](http://unbit.com/) + +`uwsgi` is the creation of [Unbit](http://unbit.com/). + +""" + +setup( + name='pyuwsgi', + license='GPL2', + version=uwsgiconfig.uwsgi_version, + author='Unbit', + author_email='[email protected]', + description='The uWSGI server', + long_description=LONG_DESCRIPTION, + long_description_content_type="text/markdown", + cmdclass={ + 'build_ext': uWSGIBuildExt, + }, + py_modules=[ + 'uwsgidecorators', + ], + ext_modules=[ + Extension('pyuwsgi', sources=[]), + ], + entry_points={ + 'console_scripts': ['pyuwsgi=pyuwsgi:run'], + }, + classifiers=[ + "Development Status :: 4 - Beta", + "Environment :: Web Environment", + "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", + "Operating System :: MacOS :: MacOS X", + "Operating System :: POSIX", + "Programming Language :: Python", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Server", + "Topic :: Internet :: WWW/HTTP :: Dynamic Content", + ] + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/uwsgi.gemspec new/uwsgi-2.0.18/uwsgi.gemspec --- old/uwsgi-2.0.17.1/uwsgi.gemspec 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/uwsgi.gemspec 2019-02-09 15:48:07.000000000 +0100 @@ -2,7 +2,7 @@ s.name = 'uwsgi' s.license = 'GPL-2' s.version = `python -c "import uwsgiconfig as uc; print uc.uwsgi_version"`.sub(/-dev-.*/,'') - s.date = '2018-07-08' + s.date = '2019-02-09' s.summary = "uWSGI" s.description = "The uWSGI server for Ruby/Rack" s.authors = ["Unbit"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uwsgi-2.0.17.1/uwsgiconfig.py new/uwsgi-2.0.18/uwsgiconfig.py --- old/uwsgi-2.0.17.1/uwsgiconfig.py 2018-07-08 19:33:15.000000000 +0200 +++ new/uwsgi-2.0.18/uwsgiconfig.py 2019-02-09 15:48:07.000000000 +0100 @@ -1,6 +1,6 @@ # uWSGI build system -uwsgi_version = '2.0.17.1' +uwsgi_version = '2.0.18' import os import re
