This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author aixtools@gmail.com
Recipients aixtools@gmail.com
Date 2016-07-01.14:34:57
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1467383699.63.0.495142233463.issue27435@psf.upfronthosting.co.za>
In-reply-to
Content
I am opening a new issue # - about the same problem described in 26439, but now calling it a bug
rather than a behavior change. Then I did not know better - all was new, and as the "new" kid
I felt uncomfortable calling it a bug - when maybe it was just behavior I did not understand

However, with the feedback from code review I am beginning to understand what the ctypes functionality
is: ctypes.find_library() and cdll.LoadLibrary (aka CDLL)

in __init__.py it is clear that there is one entry point for LoadLibrary. For find_library(),
I assume overtime, the development led to six (6) definitions - and I am proposing a 7th.

The pseudo_code is roughly this (although import ctypes._$_platform._xxx may be incorrect syntax)
def find_library(name)
    import os,sys
    _platform = sys.platform
    import ctypes._$_platform._find_library as _find_library
    return(_find_library(name))

Unclear is how a regular .so file should be treated by find_library() when the actual file is not
prefixed by the string "lib", e.g., sudoers.so - should it only look for libsudoers.so even though

Currently it is "defined" 7 times (including the definition I added at line 79)
because - again - util.py defines find_library several times - only one of the definitions is called
dependent on the os.name or os.name + platform.

Within the os.name() and sys.platform code block there are sufficient "liberities" to call
external programs used to determine where (i.e., find) the library is - and what it's correct
prefix and suffix is.


    +6  # find_library(name) returns the pathname of a library, or None.
   +49      def find_library(name): in block if os.name == "nt"
   +71      def find_library(name): if os.name == "ce" return None
   +79      def find_library(name): if sys.platform.startswith("aix") return ctypes._aixutils.find_library(name)
   +84      def find_library(name): elif os.name == "posix" and sys.platform == "darwin":
   +95  elif os.name == "posix":
  +177          def find_library(name): inside:     if (sys.platform.startswith("freebsd")
        or sys.platform.startswith("openbsd")
        or sys.platform.startswith("dragonfly")):

  +217          def find_library(name, is64 = False): inside:    elif sys.platform == "sunos5":

  +220  else:
  +249          def find_library(name):
  +250              return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name))

++++++
Getting back to my patch development - initially I was adding code to both util.py and __init__.py
and putting everything in " startswith("aix")" blocks. 
As I thought, in error, find_library() was to make visible what CDLL was finding on it's own
I was also doing find_library() like behavior. Rather than have the same code in two files
I moved the code into a new file - now named _aixutils.py.

So, this looks like a design change, but it is not. All this code could be re-indented and inserted
into util.py. IMHO, in a separate file the changes are easier to follow.
If a seperate file means it cannot be accepted into python-2.7.X then the code needs to be moved back into
util.py

Note: the extra tests added to util.py are only for my enjoyment, i.e., verification of several cases I have
experienced while porting other packages. Think of them as not being there (for now, if not for always).

Once I knew what CDLL(None) was suppossed to 
That is why my first patch had CDLL() also calling ctypes._aixutils - to only edit once.
Once I learned how wrong I was - that was removed - and it just remained this way as "eye-candy".

+++ Closing +++

find_library() is defined multiple times, so adding one for aix is not a design change,
i.e., behavior modification rather, find_library - as defined for aix in "default block"
(elif os.name = "posix": ... else: ...) specifically calling
_findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name)) is a "bug of ommission"
because the programs the two routines called depend on: ldconfig and gcc are not, normally
present on AIX.
My patch is a different way changing line 250 from
    return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name))
to
    return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name))
        or _findAIXmember(name) or _find_Soname_dump(name)

with, of course def _findAIXmember() and def _findSoname_dump() defined within the limits of util.py
 Instead, I have "hard-coded" an approach similar to the psuedo code example.


+++ Disclaimer :P +++
As I am still relatively new, if I am still not understanding the official definition of ctypes.find_library() - I apologize.
util.py is, due to is many defines of find_library() was difficult
for me to grasp the difference between permissible and "not done".

Going back to the earliest documentation I could find for ctypes https://docs.python.org/2.6/library/ctypes.html (new in 2.5) the key lines are:

ctypes exports the cdll, and on Windows windll and oledll objects, for loading dynamic link libraries.

You load libraries by accessing them as attributes of these objects. cdll loads libraries which export functions using the standard cdecl calling convention, while ...

For find_library() - the documentation is quite clear - find_library is system dependent - mentioning that "linux", as one example, uses ldconfig to find libraries:

15.15.2.1. Finding shared libraries

When programming in a compiled language, shared libraries are accessed when compiling/linking a program, and when the program is run.

The purpose of the find_library() function is to locate a library in a way similar to what the compiler does (on platforms with several versions of a shared library the most recent should be loaded), while the ctypes library loaders act like when a program is run, and call the runtime loader directly.

The ctypes.util module provides a function which can help to determine the library to load.

ctypes.util.find_library(name)
    Try to find a library and return a pathname. name is the library name without any prefix like lib, suffix like .so, .dylib or version number (this is the form used for the posix linker option -l). If no library can be found, returns None.

The exact functionality is system dependent.

On Linux, find_library() tries to run external programs (/sbin/ldconfig, gcc, and objdump) to find the library file. It returns the filename of the library file. ....

In short, I believe there is sufficient clarity in the initial documentation - that it is an "error of ommission" (so maybe "shame on IBM" that noone took this up years ago) and has every right as Linux, Solaris, openBSD, etc.. to have the system dependent glue that is needed to work "natively" on the platform. -- but I am biased -- so if I am wrong - please be kind.

Note: goal is to have the new patch, still with _aixutil.py as a matter of textual clarity rather than as language/module syntax. If being in a different file is the primary/only objection then, when I am again able to devote time - I will move the code into an "aix" block within util.py
History
Date User Action Args
2016-07-01 14:35:00aixtools@gmail.comsetrecipients: + aixtools@gmail.com
2016-07-01 14:34:59aixtools@gmail.comsetmessageid: <1467383699.63.0.495142233463.issue27435@psf.upfronthosting.co.za>
2016-07-01 14:34:59aixtools@gmail.comlinkissue27435 messages
2016-07-01 14:34:57aixtools@gmail.comcreate