diff --git a/Lib/string.py b/Lib/string.py index d4fee391c1e..ef0334c472f 100644 --- a/Lib/string.py +++ b/Lib/string.py @@ -14,6 +14,8 @@ printable -- a string containing all ASCII characters considered printable """ +import _string + # Some strings for ctype-style character classification whitespace = ' \t\n\r\v\f' ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz' @@ -170,8 +172,8 @@ class Template(metaclass=_TemplateMetaclass): # The hard parts are reused from the C implementation. They're exposed as "_" # prefixed methods of str. -# The overall parser is implemented in str._formatter_parser. -# The field name parser is implemented in str._formatter_field_name_split +# The overall parser is implemented in _string.formatter_parser. +# The field name parser is implemented in _string.formatter_field_name_split class Formatter: def format(self, format_string, *args, **kwargs): @@ -251,7 +253,7 @@ class Formatter: # if field_name is not None, it is looked up, formatted # with format_spec and conversion and then used def parse(self, format_string): - return format_string._formatter_parser() + return _string.formatter_parser(format_string) # given a field_name, find the object it references. @@ -260,7 +262,7 @@ class Formatter: # used_args: a set of which args have been used # args, kwargs: as passed in to vformat def get_field(self, field_name, args, kwargs): - first, rest = field_name._formatter_field_name_split() + first, rest = _string.formatter_field_name_split(field_name) obj = self.get_value(first, args, kwargs) diff --git a/Misc/NEWS b/Misc/NEWS index d7db587e32b..4392432b21b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 3.2 Beta 1? Core and Builtins ----------------- +- Issue #9418: Moved private string methods ``_formatter_parser`` and + ``_formatter_field_name_split`` into a new ``_string`` module. + - Issue #9992: Remove PYTHONFSENCODING environment variable. Library diff --git a/Modules/config.c.in b/Modules/config.c.in index 3fb5dd3f4fc..34d44d5a880 100644 --- a/Modules/config.c.in +++ b/Modules/config.c.in @@ -29,6 +29,7 @@ extern PyObject* PyInit_imp(void); extern PyObject* PyInit_gc(void); extern PyObject* PyInit__ast(void); extern PyObject* _PyWarnings_Init(void); +extern PyObject* PyInit__string(void); struct _inittab _PyImport_Inittab[] = { @@ -54,6 +55,9 @@ struct _inittab _PyImport_Inittab[] = { /* This lives in _warnings.c */ {"_warnings", _PyWarnings_Init}, + /* This lives in Objects/unicodeobject.c */ + {"_string", PyInit__string}, + /* Sentinel */ {0, 0} }; diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index bc70e97be4b..126c8701133 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -1180,7 +1180,7 @@ static PyTypeObject PyFormatterIter_Type = { describing the parsed elements. It's a wrapper around stringlib/string_format.h's MarkupIterator */ static PyObject * -formatter_parser(STRINGLIB_OBJECT *self) +formatter_parser(PyObject *ignored, STRINGLIB_OBJECT *self) { formatteriterobject *it; @@ -1315,7 +1315,7 @@ static PyTypeObject PyFieldNameIter_Type = { field_name_split. The iterator it returns is a FieldNameIterator */ static PyObject * -formatter_field_name_split(STRINGLIB_OBJECT *self) +formatter_field_name_split(PyObject *ignored, STRINGLIB_OBJECT *self) { SubString first; Py_ssize_t first_idx; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 37a9070e2ff..a18eeef57ac 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8968,8 +8968,6 @@ static PyMethodDef unicode_methods[] = { {"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__}, {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__}, {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__}, - {"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS}, - {"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS}, {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS | METH_STATIC, maketrans__doc__}, {"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__}, @@ -10170,6 +10168,36 @@ PyUnicode_AsUnicodeCopy(PyObject *object) return copy; } +/* A _string module, to export formatter_parser and formatter_field_name_split + to the string.Formatter class implemented in Python. */ + +static PyMethodDef _string_methods[] = { + {"formatter_field_name_split", (PyCFunction) formatter_field_name_split, + METH_O, PyDoc_STR("split the argument as a field name")}, + {"formatter_parser", (PyCFunction) formatter_parser, + METH_O, PyDoc_STR("parse the argument as a format string")}, + {NULL, NULL} +}; + +static struct PyModuleDef _string_module = { + PyModuleDef_HEAD_INIT, + "_string", + PyDoc_STR("string helper module"), + 0, + _string_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__string(void) +{ + return PyModule_Create(&_string_module); +} + + #ifdef __cplusplus } #endif diff --git a/PC/config.c b/PC/config.c index 7d501b50e13..1fc2b40a192 100644 --- a/PC/config.c +++ b/PC/config.c @@ -62,6 +62,7 @@ extern PyObject* PyInit__io(void); extern PyObject* PyInit__pickle(void); extern PyObject* PyInit_atexit(void); extern PyObject* _PyWarnings_Init(void); +extern PyObject* PyInit__string(void); /* tools/freeze/makeconfig.py marker for additional "extern" */ /* -- ADDMODULE MARKER 1 -- */ @@ -147,6 +148,7 @@ struct _inittab _PyImport_Inittab[] = { {"builtins", NULL}, {"sys", NULL}, {"_warnings", _PyWarnings_Init}, + {"_string", PyInit__string}, {"_io", PyInit__io}, {"_pickle", PyInit__pickle},