From 6cf49cf10689bf2ff23fff05928daa23ecdf6fc2 Mon Sep 17 00:00:00 2001 From: Neal Norwitz Date: Mon, 24 Mar 2008 06:22:57 +0000 Subject: Remove the dl module per PEP 3108. --- Doc/library/dl.rst | 108 ------------------ Doc/library/sys.rst | 6 +- Doc/library/unix.rst | 1 - Lib/test/test_dl.py | 34 ------ Misc/NEWS | 2 + Modules/Setup.dist | 8 -- Modules/dlmodule.c | 279 ----------------------------------------------- PC/os2emx/Makefile | 1 - PC/os2vacpp/makefile | 13 --- PC/os2vacpp/makefile.omk | 9 -- setup.py | 11 -- 11 files changed, 5 insertions(+), 467 deletions(-) delete mode 100644 Doc/library/dl.rst delete mode 100755 Lib/test/test_dl.py delete mode 100644 Modules/dlmodule.c diff --git a/Doc/library/dl.rst b/Doc/library/dl.rst deleted file mode 100644 index de641e3..0000000 --- a/Doc/library/dl.rst +++ /dev/null @@ -1,108 +0,0 @@ - -:mod:`dl` --- Call C functions in shared objects -================================================ - -.. module:: dl - :platform: Unix - :synopsis: Call C functions in shared objects. -.. sectionauthor:: Moshe Zadka - -The :mod:`dl` module defines an interface to the :cfunc:`dlopen` function, which -is the most common interface on Unix platforms for handling dynamically linked -libraries. It allows the program to call arbitrary functions in such a library. - -.. warning:: - - The :mod:`dl` module bypasses the Python type system and error handling. If - used incorrectly it may cause segmentation faults, crashes or other incorrect - behaviour. - -.. note:: - - This module will not work unless ``sizeof(int) == sizeof(long) == sizeof(char - *)`` If this is not the case, :exc:`SystemError` will be raised on import. - -The :mod:`dl` module defines the following function: - - -.. function:: open(name[, mode=RTLD_LAZY]) - - Open a shared object file, and return a handle. Mode signifies late binding - (:const:`RTLD_LAZY`) or immediate binding (:const:`RTLD_NOW`). Default is - :const:`RTLD_LAZY`. Note that some systems do not support :const:`RTLD_NOW`. - - Return value is a :class:`dlobject`. - -The :mod:`dl` module defines the following constants: - - -.. data:: RTLD_LAZY - - Useful as an argument to :func:`open`. - - -.. data:: RTLD_NOW - - Useful as an argument to :func:`open`. Note that on systems which do not - support immediate binding, this constant will not appear in the module. For - maximum portability, use :func:`hasattr` to determine if the system supports - immediate binding. - -The :mod:`dl` module defines the following exception: - - -.. exception:: error - - Exception raised when an error has occurred inside the dynamic loading and - linking routines. - -Example:: - - >>> import dl, time - >>> a=dl.open('/lib/libc.so.6') - >>> a.call('time'), time.time() - (929723914, 929723914.498) - -This example was tried on a Debian GNU/Linux system, and is a good example of -the fact that using this module is usually a bad alternative. - - -.. _dl-objects: - -Dl Objects ----------- - -Dl objects, as returned by :func:`open` above, have the following methods: - - -.. method:: dl.close() - - Free all resources, except the memory. - - -.. method:: dl.sym(name) - - Return the pointer for the function named *name*, as a number, if it exists in - the referenced shared object, otherwise ``None``. This is useful in code like:: - - >>> if a.sym('time'): - ... a.call('time') - ... else: - ... time.time() - - (Note that this function will return a non-zero number, as zero is the *NULL* - pointer) - - -.. method:: dl.call(name[, arg1[, arg2...]]) - - Call the function named *name* in the referenced shared object. The arguments - must be either Python integers, which will be passed as is, Python strings, to - which a pointer will be passed, or ``None``, which will be passed as *NULL*. - Note that strings should only be passed to functions as :ctype:`const char\*`, - as Python will not like its string mutated. - - There must be at most 10 arguments, and arguments not given will be treated as - ``None``. The function's return value must be a C :ctype:`long`, which is a - Python integer. - diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 02a1d20..085ba64 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -304,7 +304,7 @@ always available. .. function:: getdlopenflags() Return the current value of the flags that are used for :cfunc:`dlopen` calls. - The flag constants are defined in the :mod:`dl` and :mod:`DLFCN` modules. + The flag constants are defined in the :mod:`ctypes` and :mod:`DLFCN` modules. Availability: Unix. @@ -587,8 +587,8 @@ always available. the interpreter loads extension modules. Among other things, this will enable a lazy resolving of symbols when importing a module, if called as ``sys.setdlopenflags(0)``. To share symbols across extension modules, call as - ``sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)``. Symbolic names for the - flag modules can be either found in the :mod:`dl` module, or in the :mod:`DLFCN` + ``sys.setdlopenflags(ctypes.RTLD_GLOBAL)``. Symbolic names for the + flag modules can be either found in the :mod:`ctypes` module, or in the :mod:`DLFCN` module. If :mod:`DLFCN` is not available, it can be generated from :file:`/usr/include/dlfcn.h` using the :program:`h2py` script. Availability: Unix. diff --git a/Doc/library/unix.rst b/Doc/library/unix.rst index b60af0f..1b1592e 100644 --- a/Doc/library/unix.rst +++ b/Doc/library/unix.rst @@ -17,7 +17,6 @@ of it. Here's an overview: spwd.rst grp.rst crypt.rst - dl.rst termios.rst tty.rst pty.rst diff --git a/Lib/test/test_dl.py b/Lib/test/test_dl.py deleted file mode 100755 index 606da46..0000000 --- a/Lib/test/test_dl.py +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/env python -"""Test dlmodule.c - Roger E. Masse revised strategy by Barry Warsaw -""" - -import dl -from test.test_support import verbose,TestSkipped - -sharedlibs = [ - ('/usr/lib/libc.so', 'getpid'), - ('/lib/libc.so.6', 'getpid'), - ('/usr/bin/cygwin1.dll', 'getpid'), - ('/usr/lib/libc.dylib', 'getpid'), - ] - -for s, func in sharedlibs: - try: - if verbose: - print('trying to open:', s, end=' ') - l = dl.open(s) - except dl.error as err: - if verbose: - print('failed', repr(str(err))) - pass - else: - if verbose: - print('succeeded...', end=' ') - l.call(func) - l.close() - if verbose: - print('worked!') - break -else: - raise TestSkipped('Could not open any shared libraries') diff --git a/Misc/NEWS b/Misc/NEWS index 4379997..8aa1f30 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -18,6 +18,8 @@ Core and Builtins Extension Modules ----------------- +- The dl module was removed, use the ctypes module instead. + - Use wchar_t functions in _locale module. Library diff --git a/Modules/Setup.dist b/Modules/Setup.dist index ea1b806..1c07158 100644 --- a/Modules/Setup.dist +++ b/Modules/Setup.dist @@ -295,14 +295,6 @@ _symtable symtablemodule.c #_curses_panel _curses_panel.c -lpanel -lncurses -# Generic (SunOS / SVR4) dynamic loading module. -# This is not needed for dynamic loading of Python modules -- -# it is a highly experimental and dangerous device for calling -# *arbitrary* C functions in *arbitrary* shared libraries: - -#dl dlmodule.c - - # Modules that provide persistent dictionary-like semantics. You will # probably want to arrange for at least one of them to be available on # your machine, though none are defined by default because of library diff --git a/Modules/dlmodule.c b/Modules/dlmodule.c deleted file mode 100644 index 04587f6..0000000 --- a/Modules/dlmodule.c +++ /dev/null @@ -1,279 +0,0 @@ - -/* dl module */ - -#include "Python.h" - -#include - -#ifdef __VMS -#include -#endif - -#ifndef RTLD_LAZY -#define RTLD_LAZY 1 -#endif - -typedef void *PyUnivPtr; -typedef struct { - PyObject_HEAD - PyUnivPtr *dl_handle; -} dlobject; - -static PyTypeObject Dltype; - -static PyObject *Dlerror; - -static PyObject * -newdlobject(PyUnivPtr *handle) -{ - dlobject *xp; - xp = PyObject_New(dlobject, &Dltype); - if (xp == NULL) - return NULL; - xp->dl_handle = handle; - return (PyObject *)xp; -} - -static void -dl_dealloc(dlobject *xp) -{ - if (xp->dl_handle != NULL) - dlclose(xp->dl_handle); - PyObject_Del(xp); -} - -static PyObject * -dl_close(dlobject *xp) -{ - if (xp->dl_handle != NULL) { - dlclose(xp->dl_handle); - xp->dl_handle = NULL; - } - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -dl_sym(dlobject *xp, PyObject *args) -{ - char *name; - PyUnivPtr *func; - if (PyUnicode_Check(args)) { - name = PyUnicode_AsString(args); - } else { - PyErr_Format(PyExc_TypeError, "expected string, found %.200s", - Py_TYPE(args)->tp_name); - return NULL; - } - func = dlsym(xp->dl_handle, name); - if (func == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return PyLong_FromLong((long)func); -} - -static PyObject * -dl_call(dlobject *xp, PyObject *args) -{ - PyObject *name; - long (*func)(long, long, long, long, long, - long, long, long, long, long); - long alist[10]; - long res; - Py_ssize_t i; - Py_ssize_t n = PyTuple_Size(args); - if (n < 1) { - PyErr_SetString(PyExc_TypeError, "at least a name is needed"); - return NULL; - } - name = PyTuple_GetItem(args, 0); - if (!PyUnicode_Check(name)) { - PyErr_SetString(PyExc_TypeError, - "function name must be a string"); - return NULL; - } - func = (long (*)(long, long, long, long, long, - long, long, long, long, long)) - dlsym(xp->dl_handle, PyUnicode_AsString(name)); - if (func == NULL) { - PyErr_SetString(PyExc_ValueError, dlerror()); - return NULL; - } - if (n-1 > 10) { - PyErr_SetString(PyExc_TypeError, - "too many arguments (max 10)"); - return NULL; - } - for (i = 1; i < n; i++) { - PyObject *v = PyTuple_GetItem(args, i); - if (PyLong_Check(v)) { - alist[i-1] = PyLong_AsLong(v); - if (alist[i-1] == -1 && PyErr_Occurred()) - return NULL; - } else if (PyUnicode_Check(v)) - alist[i-1] = (long)PyUnicode_AsString(v); - else if (v == Py_None) - alist[i-1] = (long) ((char *)NULL); - else { - PyErr_SetString(PyExc_TypeError, - "arguments must be int, string or None"); - return NULL; - } - } - for (; i <= 10; i++) - alist[i-1] = 0; - res = (*func)(alist[0], alist[1], alist[2], alist[3], alist[4], - alist[5], alist[6], alist[7], alist[8], alist[9]); - return PyLong_FromLong(res); -} - -static PyMethodDef dlobject_methods[] = { - {"call", (PyCFunction)dl_call, METH_VARARGS}, - {"sym", (PyCFunction)dl_sym, METH_O}, - {"close", (PyCFunction)dl_close, METH_NOARGS}, - {NULL, NULL} /* Sentinel */ -}; - -static PyObject * -dl_getattr(dlobject *xp, char *name) -{ - return Py_FindMethod(dlobject_methods, (PyObject *)xp, name); -} - - -static PyTypeObject Dltype = { - PyVarObject_HEAD_INIT(NULL, 0) - "dl.dl", /*tp_name*/ - sizeof(dlobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)dl_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)dl_getattr,/*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ -}; - -static PyObject * -dl_open(PyObject *self, PyObject *args) -{ - char *name; - int mode; - PyUnivPtr *handle; - if (sizeof(int) != sizeof(long) || - sizeof(long) != sizeof(char *)) { - PyErr_SetString(PyExc_SystemError, - "module dl requires sizeof(int) == sizeof(long) == sizeof(char*)"); - return NULL; - } - - if (PyArg_ParseTuple(args, "z:open", &name)) - mode = RTLD_LAZY; - else { - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "zi:open", &name, &mode)) - return NULL; -#ifndef RTLD_NOW - if (mode != RTLD_LAZY) { - PyErr_SetString(PyExc_ValueError, "mode must be 1"); - return NULL; - } -#endif - } - handle = dlopen(name, mode); - if (handle == NULL) { - PyErr_SetString(Dlerror, dlerror()); - return NULL; - } -#ifdef __VMS - /* Under OpenVMS dlopen doesn't do any check, just save the name - * for later use, so we have to check if the file is readable, - * the name can be a logical or a file from SYS$SHARE. - */ - if (access(name, R_OK)) { - char fname[strlen(name) + 20]; - strcpy(fname, "SYS$SHARE:"); - strcat(fname, name); - strcat(fname, ".EXE"); - if (access(fname, R_OK)) { - dlclose(handle); - PyErr_SetString(Dlerror, - "File not found or protection violation"); - return NULL; - } - } -#endif - return newdlobject(handle); -} - -static PyMethodDef dl_methods[] = { - {"open", dl_open, METH_VARARGS}, - {NULL, NULL} /* sentinel */ -}; - -/* From socketmodule.c - * Convenience routine to export an integer value. - * - * Errors are silently ignored, for better or for worse... - */ -static void -insint(PyObject *d, char *name, int value) -{ - PyObject *v = PyLong_FromLong((long) value); - if (!v || PyDict_SetItemString(d, name, v)) - PyErr_Clear(); - - Py_XDECREF(v); -} - -PyMODINIT_FUNC -initdl(void) -{ - PyObject *m, *d, *x; - - /* Initialize object type */ - Py_TYPE(&Dltype) = &PyType_Type; - - /* Create the module and add the functions */ - m = Py_InitModule("dl", dl_methods); - if (m == NULL) - return; - - /* Add some symbolic constants to the module */ - d = PyModule_GetDict(m); - Dlerror = x = PyErr_NewException("dl.error", NULL, NULL); - PyDict_SetItemString(d, "error", x); - x = PyLong_FromLong((long)RTLD_LAZY); - PyDict_SetItemString(d, "RTLD_LAZY", x); -#define INSINT(X) insint(d,#X,X) -#ifdef RTLD_NOW - INSINT(RTLD_NOW); -#endif -#ifdef RTLD_NOLOAD - INSINT(RTLD_NOLOAD); -#endif -#ifdef RTLD_GLOBAL - INSINT(RTLD_GLOBAL); -#endif -#ifdef RTLD_LOCAL - INSINT(RTLD_LOCAL); -#endif -#ifdef RTLD_PARENT - INSINT(RTLD_PARENT); -#endif -#ifdef RTLD_GROUP - INSINT(RTLD_GROUP); -#endif -#ifdef RTLD_WORLD - INSINT(RTLD_WORLD); -#endif -#ifdef RTLD_NODELETE - INSINT(RTLD_NODELETE); -#endif -} diff --git a/PC/os2emx/Makefile b/PC/os2emx/Makefile index d3ef12b..2fcb334 100644 --- a/PC/os2emx/Makefile +++ b/PC/os2emx/Makefile @@ -290,7 +290,6 @@ SRC.MODULES= $(addprefix $(TOP), \ Modules/cStringIO.c \ Modules/_csv.c \ Modules/datetimemodule.c \ - Modules/dlmodule.c \ Modules/errnomodule.c \ Modules/fcntlmodule.c \ Modules/_functoolsmodule.c \ diff --git a/PC/os2vacpp/makefile b/PC/os2vacpp/makefile index 7e79566..93cae73 100644 --- a/PC/os2vacpp/makefile +++ b/PC/os2vacpp/makefile @@ -507,19 +507,6 @@ dbmmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\clas $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \ $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h -dlmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \ - $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \ - $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \ - $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h $(PY_INCLUDE)\intobject.h \ - $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h $(PY_INCLUDE)\longobject.h \ - $(PY_INCLUDE)\methodobject.h $(PY_INCLUDE)\modsupport.h \ - $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h $(PY_INCLUDE)\myproto.h \ - $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h $(PY_INCLUDE)\pydebug.h \ - $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h $(PY_INCLUDE)\pystate.h \ - $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h $(PY_INCLUDE)\rangeobject.h \ - $(PY_INCLUDE)\sliceobject.h $(PY_INCLUDE)\stringobject.h \ - $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h - errno.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \ $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \ $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h $(PY_INCLUDE)\floatobject.h \ diff --git a/PC/os2vacpp/makefile.omk b/PC/os2vacpp/makefile.omk index f0ed273..2e0aae3 100644 --- a/PC/os2vacpp/makefile.omk +++ b/PC/os2vacpp/makefile.omk @@ -201,7 +201,6 @@ MODULES = \ # zlibmodule.c -- Wrapper of ZLib Compression API (GZip Format) # puremodule.c -- Wrapper of Purify Debugging API (Probably Non-OS/2) - # dlmodule.c -- Some Wierd Form of Data Processing Module # xxmodule.c -- Template to Create Your Own Module # @@ -419,14 +418,6 @@ dbmmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \ pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \ traceback.h tupleobject.h -dlmodule.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \ - pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \ - import.h intobject.h intrcheck.h listobject.h longobject.h \ - methodobject.h modsupport.h moduleobject.h mymalloc.h myproto.h \ - object.h objimpl.h pydebug.h pyerrors.h pyfpe.h pystate.h python.h \ - pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \ - traceback.h tupleobject.h - errno.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \ pyconfig.h dictobject.h fileobject.h floatobject.h funcobject.h \ import.h intobject.h intrcheck.h listobject.h longobject.h \ diff --git a/setup.py b/setup.py index be34cd1..2bfa91b 100644 --- a/setup.py +++ b/setup.py @@ -1105,17 +1105,6 @@ class PyBuildExt(build_ext): exts.append(Extension('_codecs_%s' % loc, ['cjkcodecs/_codecs_%s.c' % loc])) - # Dynamic loading module - if sys.maxsize == 0x7fffffff: - # This requires sizeof(int) == sizeof(long) == sizeof(char*) - dl_inc = find_file('dlfcn.h', [], inc_dirs) - if (dl_inc is not None) and (platform not in ['atheos']): - exts.append( Extension('dl', ['dlmodule.c']) ) - else: - missing.append('dl') - else: - missing.append('dl') - # Thomas Heller's _ctypes module self.detect_ctypes(inc_dirs, lib_dirs) -- cgit v0.12