installing fixed versions of standard modules.)
Paths can be absolute or relative, in which case they're relative to the
-directory containing the :file:`.pth` file. Any directories added to the search
-path will be scanned in turn for :file:`.pth` files. See the documentation of
+directory containing the :file:`.pth` file. See the documentation of
the :mod:`site` module for more information.
A slightly less convenient way is to edit the :file:`site.py` file in Python's
def __asdict__(self):
'Return a new dict mapping field names to their values'
return dict(zip(('x', 'y'), self))
- def __replace__(self, field, value):
+ def __replace__(self, **kwds):
'Return a new Point object replacing specified fields with new values'
return Point(**dict(zip(('x', 'y'), self) + kwds.items()))
x = property(itemgetter(0))
#define PyImport_ImportModuleEx(n, g, l, f) \
PyImport_ImportModuleLevel(n, g, l, f, -1)
+PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path);
PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name);
PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m);
PyAPI_FUNC(void) PyImport_Cleanup(void);
void (*initfunc)(void);
};
+PyAPI_DATA(PyTypeObject) PyNullImporter_Type;
PyAPI_DATA(struct _inittab *) PyImport_Inittab;
PyAPI_FUNC(int) PyImport_AppendInittab(char *name, void (*initfunc)(void));
self.checkequal(3, 'abc', 'find', '', 3)
self.checkequal(-1, 'abc', 'find', '', 4)
+ # to check the ability to pass None as defaults
+ self.checkequal( 2, 'rrarrrrrrrrra', 'find', 'a')
+ self.checkequal(12, 'rrarrrrrrrrra', 'find', 'a', 4)
+ self.checkequal(-1, 'rrarrrrrrrrra', 'find', 'a', 4, 6)
+ self.checkequal(12, 'rrarrrrrrrrra', 'find', 'a', 4, None)
+ self.checkequal( 2, 'rrarrrrrrrrra', 'find', 'a', None, 6)
+
self.checkraises(TypeError, 'hello', 'find')
self.checkraises(TypeError, 'hello', 'find', 42)
self.checkequal(3, 'abc', 'rfind', '', 3)
self.checkequal(-1, 'abc', 'rfind', '', 4)
+ # to check the ability to pass None as defaults
+ self.checkequal(12, 'rrarrrrrrrrra', 'rfind', 'a')
+ self.checkequal(12, 'rrarrrrrrrrra', 'rfind', 'a', 4)
+ self.checkequal(-1, 'rrarrrrrrrrra', 'rfind', 'a', 4, 6)
+ self.checkequal(12, 'rrarrrrrrrrra', 'rfind', 'a', 4, None)
+ self.checkequal( 2, 'rrarrrrrrrrra', 'rfind', 'a', None, 6)
+
self.checkraises(TypeError, 'hello', 'rfind')
self.checkraises(TypeError, 'hello', 'rfind', 42)
self.checkraises(ValueError, 'abcdefghi', 'index', 'ghi', 8)
self.checkraises(ValueError, 'abcdefghi', 'index', 'ghi', -1)
+ # to check the ability to pass None as defaults
+ self.checkequal( 2, 'rrarrrrrrrrra', 'index', 'a')
+ self.checkequal(12, 'rrarrrrrrrrra', 'index', 'a', 4)
+ self.checkraises(ValueError, 'rrarrrrrrrrra', 'index', 'a', 4, 6)
+ self.checkequal(12, 'rrarrrrrrrrra', 'index', 'a', 4, None)
+ self.checkequal( 2, 'rrarrrrrrrrra', 'index', 'a', None, 6)
+
self.checkraises(TypeError, 'hello', 'index')
self.checkraises(TypeError, 'hello', 'index', 42)
self.checkraises(ValueError, 'abcdefghi', 'rindex', 'ghi', 0, 8)
self.checkraises(ValueError, 'abcdefghi', 'rindex', 'ghi', 0, -1)
+ # to check the ability to pass None as defaults
+ self.checkequal(12, 'rrarrrrrrrrra', 'rindex', 'a')
+ self.checkequal(12, 'rrarrrrrrrrra', 'rindex', 'a', 4)
+ self.checkraises(ValueError, 'rrarrrrrrrrra', 'rindex', 'a', 4, 6)
+ self.checkequal(12, 'rrarrrrrrrrra', 'rindex', 'a', 4, None)
+ self.checkequal( 2, 'rrarrrrrrrrra', 'rindex', 'a', None, 6)
+
self.checkraises(TypeError, 'hello', 'rindex')
self.checkraises(TypeError, 'hello', 'rindex', 42)
+# Tests invocation of the interpreter with various command line arguments
+# All tests are executed with environment variables ignored
+# See test_cmd_line_script.py for testing of script execution
import test.test_support, unittest
import sys
--- /dev/null
+# Tests command line execution of scripts
+from __future__ import with_statement
+
+import unittest
+import os
+import os.path
+import sys
+import test
+import tempfile
+import subprocess
+import py_compile
+import contextlib
+import shutil
+import zipfile
+
+verbose = test.test_support.verbose
+
+# XXX ncoghlan: Should we consider moving these to test_support?
+from .test_cmd_line import _spawn_python, _kill_python
+
+def _run_python(*args):
+ if __debug__:
+ p = _spawn_python(*args)
+ else:
+ p = _spawn_python('-O', *args)
+ stdout_data = _kill_python(p)
+ return p.wait(), stdout_data.decode()
+
+@contextlib.contextmanager
+def temp_dir():
+ dirname = tempfile.mkdtemp()
+ try:
+ yield dirname
+ finally:
+ shutil.rmtree(dirname)
+
+test_source = ("""\
+# Script may be run with optimisation enabled, so don't rely on assert
+# statements being executed
+def assertEqual(lhs, rhs):
+ if lhs != rhs:
+ raise AssertionError("%r != %r" % (lhs, rhs))
+def assertIdentical(lhs, rhs):
+ if lhs is not rhs:
+ raise AssertionError("%r is not %r" % (lhs, rhs))
+# Check basic code execution
+result = ['Top level assignment']
+def f():
+ result.append('Lower level reference')
+f()
+assertEqual(result, ['Top level assignment', 'Lower level reference'])
+# Check population of magic variables
+assertEqual(__name__, '__main__')
+print('__file__==%r' % __file__)
+# Check the sys module
+import sys
+assertIdentical(globals(), sys.modules[__name__].__dict__)
+print('sys.argv[0]==%r' % sys.argv[0])
+""")
+
+def _make_test_script(script_dir, script_basename):
+ script_filename = script_basename+os.path.extsep+"py"
+ script_name = os.path.join(script_dir, script_filename)
+ script_file = open(script_name, "w")
+ script_file.write(test_source)
+ script_file.close()
+ return script_name
+
+def _compile_test_script(script_name):
+ py_compile.compile(script_name, doraise=True)
+ if __debug__:
+ compiled_name = script_name + 'c'
+ else:
+ compiled_name = script_name + 'o'
+ return compiled_name
+
+def _make_test_zip(zip_dir, zip_basename, script_name):
+ zip_filename = zip_basename+os.path.extsep+"zip"
+ zip_name = os.path.join(zip_dir, zip_filename)
+ zip_file = zipfile.ZipFile(zip_name, 'w')
+ zip_file.write(script_name, os.path.basename(script_name))
+ zip_file.close()
+ # if verbose:
+ # zip_file = zipfile.ZipFile(zip_name, 'r')
+ # print "Contents of %r:" % zip_name
+ # zip_file.printdir()
+ # zip_file.close()
+ return zip_name
+
+class CmdLineTest(unittest.TestCase):
+ def _check_script(self, script_name, expected_file, expected_argv0):
+ exit_code, data = _run_python(script_name)
+ # if verbose:
+ # print "Output from test script %r:" % script_name
+ # print data
+ self.assertEqual(exit_code, 0, data)
+ printed_file = '__file__==%r' % expected_file
+ printed_argv0 = 'sys.argv[0]==%r' % expected_argv0
+ self.assert_(printed_file in data, (printed_file, data))
+ self.assert_(printed_argv0 in data, (printed_argv0, data))
+
+ def test_basic_script(self):
+ with temp_dir() as script_dir:
+ script_name = _make_test_script(script_dir, "script")
+ self._check_script(script_name, script_name, script_name)
+
+ def test_script_compiled(self):
+ with temp_dir() as script_dir:
+ script_name = _make_test_script(script_dir, "script")
+ compiled_name = _compile_test_script(script_name)
+ os.remove(script_name)
+ self._check_script(compiled_name, compiled_name, compiled_name)
+
+ def test_directory(self):
+ with temp_dir() as script_dir:
+ script_name = _make_test_script(script_dir, "__main__")
+ self._check_script(script_dir, script_name, script_dir)
+
+ def test_directory_compiled(self):
+ with temp_dir() as script_dir:
+ script_name = _make_test_script(script_dir, "__main__")
+ compiled_name = _compile_test_script(script_name)
+ os.remove(script_name)
+ self._check_script(script_dir, compiled_name, script_dir)
+
+ def test_zipfile(self):
+ with temp_dir() as script_dir:
+ script_name = _make_test_script(script_dir, "__main__")
+ zip_name = _make_test_zip(script_dir, "test_zip", script_name)
+ self._check_script(zip_name, None, zip_name)
+
+ def test_zipfile_compiled(self):
+ with temp_dir() as script_dir:
+ script_name = _make_test_script(script_dir, "__main__")
+ compiled_name = _compile_test_script(script_name)
+ zip_name = _make_test_zip(script_dir, "test_zip", compiled_name)
+ self._check_script(zip_name, None, zip_name)
+
+
+def test_main():
+ test.test_support.run_unittest(CmdLineTest)
+ test.test_support.reap_children()
+
+if __name__ == "__main__":
+ test_main()
}
-static int RunModule(char *module)
+static int RunModule(char *module, int set_argv0)
{
PyObject *runpy, *runmodule, *runargs, *result;
runpy = PyImport_ImportModule("runpy");
Py_DECREF(runpy);
return -1;
}
- runargs = Py_BuildValue("(s)", module);
+ runargs = Py_BuildValue("(si)", module, set_argv0);
if (runargs == NULL) {
fprintf(stderr,
"Could not create arguments for runpy._run_module_as_main\n");
return 0;
}
+static int RunMainFromImporter(char *filename)
+{
+ PyObject *argv0 = NULL, *importer = NULL;
+
+ if (
+ (argv0 = PyString_FromString(filename)) &&
+ (importer = PyImport_GetImporter(argv0)) &&
+ (importer->ob_type != &PyNullImporter_Type))
+ {
+ /* argv0 is usable as an import source, so
+ put it in sys.path[0] and import __main__ */
+ PyObject *sys_path = NULL;
+ if (
+ (sys_path = PySys_GetObject("path")) &&
+ !PyList_SetItem(sys_path, 0, argv0)
+ ) {
+ Py_INCREF(argv0);
+ Py_CLEAR(importer);
+ sys_path = NULL;
+ return RunModule("__main__", 0) != 0;
+ }
+ }
+ PyErr_Clear();
+ Py_CLEAR(argv0);
+ Py_CLEAR(importer);
+ return -1;
+}
+
+
/* Wait until threading._shutdown completes, provided
the threading module was imported in the first place.
The shutdown routine will wait until all non-daemon
#else
filename = argv[_PyOS_optind];
#endif
- if (filename != NULL) {
- if ((fp = fopen(filename, "r")) == NULL) {
-#ifdef HAVE_STRERROR
- fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
- argv[0], filename, errno, strerror(errno));
-#else
- fprintf(stderr, "%s: can't open file '%s': Errno %d\n",
- argv[0], filename, errno);
-#endif
- return 2;
- }
- else if (skipfirstline) {
- int ch;
- /* Push back first newline so line numbers
- remain the same */
- while ((ch = getc(fp)) != EOF) {
- if (ch == '\n') {
- (void)ungetc(ch, fp);
- break;
- }
- }
- }
- {
- /* XXX: does this work on Win/Win64? (see posix_fstat) */
- struct stat sb;
- if (fstat(fileno(fp), &sb) == 0 &&
- S_ISDIR(sb.st_mode)) {
- fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename);
- fclose(fp);
- return 1;
- }
- }
- }
}
stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
sts = PyRun_SimpleStringFlags(command, &cf) != 0;
free(command);
} else if (module) {
- sts = RunModule(module);
+ sts = RunModule(module, 1);
free(module);
}
else {
+
if (filename == NULL && stdin_is_interactive) {
Py_InspectFlag = 0; /* do exit on SystemExit */
RunStartupFile(&cf);
}
/* XXX */
- sts = PyRun_AnyFileExFlags(
- fp,
- filename == NULL ? "<stdin>" : filename,
- filename != NULL, &cf) != 0;
+
+ sts = -1; /* keep track of whether we've already run __main__ */
+
+ if (filename != NULL) {
+ sts = RunMainFromImporter(filename);
+ }
+
+ if (sts==-1 && filename!=NULL) {
+ if ((fp = fopen(filename, "r")) == NULL) {
+#ifdef HAVE_STRERROR
+ fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
+ argv[0], filename, errno, strerror(errno));
+#else
+ fprintf(stderr, "%s: can't open file '%s': Errno %d\n",
+ argv[0], filename, errno);
+#endif
+ return 2;
+ }
+ else if (skipfirstline) {
+ int ch;
+ /* Push back first newline so line numbers
+ remain the same */
+ while ((ch = getc(fp)) != EOF) {
+ if (ch == '\n') {
+ (void)ungetc(ch, fp);
+ break;
+ }
+ }
+ }
+ {
+ /* XXX: does this work on Win/Win64? (see posix_fstat) */
+ struct stat sb;
+ if (fstat(fileno(fp), &sb) == 0 &&
+ S_ISDIR(sb.st_mode)) {
+ fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename);
+ return 1;
+ }
+ }
+ }
+
+ if (sts==-1) {
+ sts = PyRun_AnyFileExFlags(
+ fp,
+ filename == NULL ? "<stdin>" : filename,
+ filename != NULL, &cf) != 0;
+ }
+
}
/* Check this environment variable at the end, to give programs the
#endif /* STRINGLIB_STR */
+#ifdef FROM_UNICODE
+
+/*
+This function is a helper for the "find" family (find, rfind, index,
+rindex) of unicodeobject.c file, because they all have the same
+behaviour for the arguments.
+
+It does not touch the variables received until it knows everything
+is ok.
+
+Note that we receive a pointer to the pointer of the substring object,
+so when we create that object in this function we don't DECREF it,
+because it continues living in the caller functions (those functions,
+after finishing using the substring, must DECREF it).
+*/
+
+Py_LOCAL_INLINE(int)
+_ParseTupleFinds (PyObject *args, PyObject **substring,
+ Py_ssize_t *start, Py_ssize_t *end) {
+ PyObject *tmp_substring;
+ Py_ssize_t tmp_start = 0;
+ Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
+ PyObject *obj_start=Py_None, *obj_end=Py_None;
+
+ if (!PyArg_ParseTuple(args, "O|OO:find", &tmp_substring,
+ &obj_start, &obj_end))
+ return 0;
+
+ /* To support None in "start" and "end" arguments, meaning
+ the same as if they were not passed.
+ */
+ if (obj_start != Py_None)
+ if (!_PyEval_SliceIndex(obj_start, &tmp_start))
+ return 0;
+ if (obj_end != Py_None)
+ if (!_PyEval_SliceIndex(obj_end, &tmp_end))
+ return 0;
+
+ tmp_substring = PyUnicode_FromObject(tmp_substring);
+ if (!tmp_substring)
+ return 0;
+
+ *start = tmp_start;
+ *end = tmp_end;
+ *substring = tmp_substring;
+ return 1;
+}
+
+#endif /* FROM_UNICODE */
+
#endif /* STRINGLIB_FIND_H */
/*
const char *sub;
Py_ssize_t sub_len;
Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
+ PyObject *obj_start=Py_None, *obj_end=Py_None;
- if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!PyArg_ParseTuple(args, "O|OO:find/rfind/index/rindex", &subobj,
+ &obj_start, &obj_end))
return -2;
+ /* To support None in "start" and "end" arguments, meaning
+ the same as if they were not passed.
+ */
+ if (obj_start != Py_None)
+ if (!_PyEval_SliceIndex(obj_start, &start))
+ return -2;
+ if (obj_end != Py_None)
+ if (!_PyEval_SliceIndex(obj_end, &end))
+ return -2;
+
if (PyString_Check(subobj)) {
sub = PyString_AS_STRING(subobj);
sub_len = PyString_GET_SIZE(subobj);
/* --- Helpers ------------------------------------------------------------ */
#include "stringlib/unicodedefs.h"
-
#include "stringlib/fastsearch.h"
-
#include "stringlib/count.h"
+/* Include _ParseTupleFinds from find.h */
+#define FROM_UNICODE
#include "stringlib/find.h"
#include "stringlib/partition.h"
unicode_find(PyUnicodeObject *self, PyObject *args)
{
PyObject *substring;
- Py_ssize_t start = 0;
- Py_ssize_t end = PY_SSIZE_T_MAX;
+ Py_ssize_t start;
+ Py_ssize_t end;
Py_ssize_t result;
- if (!PyArg_ParseTuple(args, "O|O&O&:find", &substring,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!_ParseTupleFinds(args, &substring, &start, &end))
return NULL;
- substring = PyUnicode_FromObject(substring);
- if (!substring)
- return NULL;
result = stringlib_find_slice(
PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
{
Py_ssize_t result;
PyObject *substring;
- Py_ssize_t start = 0;
- Py_ssize_t end = PY_SSIZE_T_MAX;
+ Py_ssize_t start;
+ Py_ssize_t end;
- if (!PyArg_ParseTuple(args, "O|O&O&:index", &substring,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!_ParseTupleFinds(args, &substring, &start, &end))
return NULL;
- substring = PyUnicode_FromObject(substring);
- if (!substring)
- return NULL;
result = stringlib_find_slice(
PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
unicode_rfind(PyUnicodeObject *self, PyObject *args)
{
PyObject *substring;
- Py_ssize_t start = 0;
- Py_ssize_t end = PY_SSIZE_T_MAX;
+ Py_ssize_t start;
+ Py_ssize_t end;
Py_ssize_t result;
- if (!PyArg_ParseTuple(args, "O|O&O&:rfind", &substring,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
- return NULL;
- substring = PyUnicode_FromObject(substring);
- if (!substring)
- return NULL;
+ if (!_ParseTupleFinds(args, &substring, &start, &end))
+ return NULL;
result = stringlib_rfind_slice(
PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
unicode_rindex(PyUnicodeObject *self, PyObject *args)
{
PyObject *substring;
- Py_ssize_t start = 0;
- Py_ssize_t end = PY_SSIZE_T_MAX;
+ Py_ssize_t start;
+ Py_ssize_t end;
Py_ssize_t result;
- if (!PyArg_ParseTuple(args, "O|O&O&:rindex", &substring,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
- return NULL;
- substring = PyUnicode_FromObject(substring);
- if (!substring)
- return NULL;
+ if (!_ParseTupleFinds(args, &substring, &start, &end))
+ return NULL;
result = stringlib_rfind_slice(
PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
{0, 0}
};
-static PyTypeObject NullImporterType; /* Forward reference */
/* Initialize things */
/* adding sys.path_hooks and sys.path_importer_cache, setting up
zipimport */
- if (PyType_Ready(&NullImporterType) < 0)
+ if (PyType_Ready(&PyNullImporter_Type) < 0)
goto error;
if (Py_VerboseFlag)
}
if (importer == NULL) {
importer = PyObject_CallFunctionObjArgs(
- (PyObject *)&NullImporterType, p, NULL
+ (PyObject *)&PyNullImporter_Type, p, NULL
);
if (importer == NULL) {
if (PyErr_ExceptionMatches(PyExc_ImportError)) {
return importer;
}
+PyAPI_FUNC(PyObject *)
+PyImport_GetImporter(PyObject *path) {
+ PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL;
+
+ if ((path_importer_cache = PySys_GetObject("path_importer_cache"))) {
+ if ((path_hooks = PySys_GetObject("path_hooks"))) {
+ importer = get_path_importer(path_importer_cache,
+ path_hooks, path);
+ }
+ }
+ Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */
+ return importer;
+}
+
/* Search the path (default sys.path) for a module. Return the
corresponding filedescr struct, and (via return arguments) the
pathname and an open file. Return NULL if the module is not found. */
};
-static PyTypeObject NullImporterType = {
+PyTypeObject PyNullImporter_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"imp.NullImporter", /*tp_name*/
sizeof(NullImporter), /*tp_basicsize*/
{
PyObject *m, *d;
- if (PyType_Ready(&NullImporterType) < 0)
+ if (PyType_Ready(&PyNullImporter_Type) < 0)
goto failure;
m = Py_InitModule4("imp", imp_methods, doc_imp,
if (setint(d, "PY_CODERESOURCE", PY_CODERESOURCE) < 0) goto failure;
if (setint(d, "IMP_HOOK", IMP_HOOK) < 0) goto failure;
- Py_INCREF(&NullImporterType);
- PyModule_AddObject(m, "NullImporter", (PyObject *)&NullImporterType);
+ Py_INCREF(&PyNullImporter_Type);
+ PyModule_AddObject(m, "NullImporter", (PyObject *)&PyNullImporter_Type);
failure:
;
}