Доступ к errno из Python?

Вам не хватает атрибута 'ordered' См. Ниже

attributes: {
      availableFanSpeeds: {
        speeds: [{
          speed_name: 'Low',
          speed_values: [{
            speed_synonym: ['low', 'slow'],
            lang: 'en'
          }, {
            speed_synonym: ['low', 'slow'],
            lang: 'de'
          }]
        }, {
          speed_name: 'High',
          speed_values: [{
            speed_synonym: ['high'],
            lang: 'en'
          }, {
            speed_synonym: ['high'],
            lang: 'de'
          }]
        }],
        'ordered':true
      },
      reversible: true
    }
22
задан Adam Smith 8 May 2014 в 21:35
поделиться

5 ответов

Обновление: На [1 113] Python 2.6 + , используйте ctypes.get_errno() .

Python 2.5

код Belowed не является надежным (или всесторонним, существует plefora путей errno, мог быть определен), но это должно получить Вас, запустился (или пересмотрите свою позицию по крошечному дополнительному модулю (в конце концов, на Debian python setup.py install, или easy_install не должен иметь никакой проблемы для создания его)). От http://codespeak.net/pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py

if not hasattr(ctypes, 'get_errno'):
    # Python 2.5 or older
    if sys.platform == 'win32':
        standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int)
        def _where_is_errno():
            return standard_c_lib._errno()

    elif sys.platform in ('linux2', 'freebsd6'):
        standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int)
        def _where_is_errno():
            return standard_c_lib.__errno_location()

    elif sys.platform in ('darwin', 'freebsd7'):
        standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int)
        def _where_is_errno():
            return standard_c_lib.__error()
    ctypes.get_errno = lambda: _where_is_errno().contents.value 

, Где standard_c_lib:

def get_libc_name():
    if sys.platform == 'win32':
        # Parses sys.version and deduces the version of the compiler
        import distutils.msvccompiler
        version = distutils.msvccompiler.get_build_version()
        if version is None:
            # This logic works with official builds of Python.
            if sys.version_info < (2, 4):
                clibname = 'msvcrt'
            else:
                clibname = 'msvcr71'
        else:
            if version <= 6:
                clibname = 'msvcrt'
            else:
                clibname = 'msvcr%d' % (version * 10)

        # If python was built with in debug mode
        import imp
        if imp.get_suffixes()[0][0] == '_d.pyd':
            clibname += 'd'

        return clibname+'.dll'
    else:
        return ctypes.util.find_library('c')

# Make sure the name is determined during import, not at runtime
libc_name = get_libc_name() 
standard_c_lib = ctypes.cdll.LoadLibrary(get_libc_name())
14
ответ дан 29 November 2019 в 04:15
поделиться

Вот отрывок кода, который позволяет получать доступ errno:

from ctypes import *

libc = CDLL("libc.so.6")

get_errno_loc = libc.__errno_location
get_errno_loc.restype = POINTER(c_int)

def errcheck(ret, func, args):
    if ret == -1:
        e = get_errno_loc()[0]
        raise OSError(e)
    return ret

copen = libc.open
copen.errcheck = errcheck

print copen("nosuchfile", 0)

важная вещь состоит в том, что Вы проверяете errno как можно скорее после Вашего вызова функции, иначе он может уже быть перезаписан.

17
ответ дан 29 November 2019 в 04:15
поделиться

Похоже, вы можете использовать этот патч, который предоставит вам ctypes.get_errno/set_errno

http://bugs.python.org/issue1798

Это патч, который фактически был применен к хранилищу:

http://svn.python.org/view?view=rev&revision=63977

В противном случае добавляем новый модуль C, который ничего не делает, но возвращает errno / is / disgusting, но также и библиотека, которую вы используете. Я бы предпочел сделать патч для Python самостоятельно.

9
ответ дан 29 November 2019 в 04:15
поделиться

Сдался и отследил через заголовки C.

import ctypes
c = ctypes.CDLL("libc.so.6")
c.__errno_location.restype = ctypes.POINTER(ctypes.c_int)
c.write(5000, "foo", 4)
print c.__errno_location().contents # -> c_long(9)

Это не работает в командной строке Python, потому что это сбрасывает errno для чтения из stdin.

, Как только Вы знаете волшебное слово __ errno_location, это похоже на общий шаблон. Но со всего errno я был довольно потерян.

9
ответ дан 29 November 2019 в 04:15
поделиться

Я не уверен, является ли это тем, к чему Вы и Jerub обращаетесь, но Вы могли записать очень короткое расширение C, которое просто экспортирует errno, т.е. с интерфейс языка Python .

Иначе, я соглашаюсь с Вами, что необходимость добавить этот маленький бит скомпилированного кода является болью.

1
ответ дан 29 November 2019 в 04:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: