Issue #4859: Implement PEP 383 for pwd, spwd, and grp.
diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c
index a58cb06..e642731 100644
--- a/Modules/grpmodule.c
+++ b/Modules/grpmodule.c
@@ -46,8 +46,11 @@
         Py_DECREF(v);
         return NULL;
     }
+#define FSDECODE(val) PyUnicode_Decode(val, strlen(val),\
+                                       Py_FileSystemDefaultEncoding,\
+                                       "surrogateescape")
     for (member = p->gr_mem; *member != NULL; member++) {
-        PyObject *x = PyUnicode_FromString(*member);
+        PyObject *x = FSDECODE(*member);
         if (x == NULL || PyList_Append(w, x) != 0) {
             Py_XDECREF(x);
             Py_DECREF(w);
@@ -58,13 +61,13 @@
     }
 
 #define SET(i,val) PyStructSequence_SET_ITEM(v, i, val)
-    SET(setIndex++, PyUnicode_FromString(p->gr_name));
+    SET(setIndex++, FSDECODE(p->gr_name));
 #ifdef __VMS
     SET(setIndex++, Py_None);
     Py_INCREF(Py_None);
 #else
     if (p->gr_passwd)
-	    SET(setIndex++, PyUnicode_FromString(p->gr_passwd));
+	    SET(setIndex++, FSDECODE(p->gr_passwd));
     else {
 	    SET(setIndex++, Py_None);
 	    Py_INCREF(Py_None);
@@ -104,25 +107,28 @@
 }
 
 static PyObject *
-grp_getgrnam(PyObject *self, PyObject *pyo_name)
+grp_getgrnam(PyObject *self, PyObject *args)
 {
-    PyObject *py_str_name;
     char *name;
     struct group *p;
+    PyObject *arg, *bytes, *retval = NULL;
 
-    py_str_name = PyObject_Str(pyo_name);
-    if (!py_str_name)
-	    return NULL;
-    name = _PyUnicode_AsString(py_str_name);
+    if (!PyArg_ParseTuple(args, "U:getgrnam", &arg))
+        return NULL;
+    if ((bytes = PyUnicode_AsEncodedString(arg, Py_FileSystemDefaultEncoding,
+                                           "surrogateescape")) == NULL)
+        return NULL;
+    if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
+        goto out;
     
     if ((p = getgrnam(name)) == NULL) {
 	PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
-	Py_DECREF(py_str_name);
-        return NULL;
+        goto out;
     }
-
-    Py_DECREF(py_str_name);
-    return mkgrent(p);
+    retval = mkgrent(p);
+out:
+    Py_DECREF(bytes);
+    return retval;
 }
 
 static PyObject *
@@ -152,7 +158,7 @@
      "getgrgid(id) -> tuple\n\
 Return the group database entry for the given numeric group ID.  If\n\
 id is not valid, raise KeyError."},
-    {"getgrnam",	grp_getgrnam,	METH_O,
+    {"getgrnam",	grp_getgrnam,	METH_VARARGS,
      "getgrnam(name) -> tuple\n\
 Return the group database entry for the given group name.  If\n\
 name is not valid, raise KeyError."},