Поиск исходного кода методов, реализованных в C? - PullRequest
0 голосов
/ 24 октября 2018

Обратите внимание: я задаю этот вопрос только в информационных целях.

Мне известно, что название звучит как дубликат Поиск исходного кода для встроенных функций Python? .Но позвольте мне объяснить.

Скажем, например, я хочу найти исходный код метода most_common класса collections.Counter.Так как класс Counter реализован на python, я мог бы использовать модуль inspect, чтобы получить его исходный код.

, т. Е.

>>> import inspect
>>> import collections
>>> print(inspect.getsource(collections.Counter.most_common))

Это выведет

    def most_common(self, n=None):
        '''List the n most common elements and their counts from the most
        common to the least.  If n is None, then list all element counts.

        >>> Counter('abcdeabcdabcaba').most_common(3)
        [('a', 5), ('b', 4), ('c', 3)]

        '''
        # Emulate Bag.sortedByCount from Smalltalk
        if n is None:
            return sorted(self.items(), key=_itemgetter(1), reverse=True)
        return _heapq.nlargest(n, self.items(), key=_itemgetter(1))

Так что, если метод или класс, реализованный в C inspect.getsource, вызовет TypeError.

>>> my_list = []
>>> print(inspect.getsource(my_list.append))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\abdul.niyas\AppData\Local\Programs\Python\Python36-32\lib\inspect.py", line 968, in getsource
    lines, lnum = getsourcelines(object)
  File "C:\Users\abdul.niyas\AppData\Local\Programs\Python\Python36-32\lib\inspect.py", line 955, in getsourcelines
    lines, lnum = findsource(object)
  File "C:\Users\abdul.niyas\AppData\Local\Programs\Python\Python36-32\lib\inspect.py", line 768, in findsource
    file = getsourcefile(object)
  File "C:\Users\abdul.niyas\AppData\Local\Programs\Python\Python36-32\lib\inspect.py", line 684, in getsourcefile
    filename = getfile(object)
  File "C:\Users\abdul.niyas\AppData\Local\Programs\Python\Python36-32\lib\inspect.py", line 666, in getfile
    'function, traceback, frame, or code object'.format(object))
TypeError: <built-in method append of list object at 0x00D3A378> is not a module, class, method, function, traceback, frame, or code object.

Итак, мой вопрос: есть ли способ (или использование стороннего пакета?), Что мыможно найти исходный код класса или метода, реализованного также в C?

т.е. что-то вроде этого

>> print(some_how_or_some_custom_package([].append))


int
PyList_Append(PyObject *op, PyObject *newitem)
{
    if (PyList_Check(op) && (newitem != NULL))
        return app1((PyListObject *)op, newitem);
    PyErr_BadInternalCall();
    return -1;
}

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Может быть, если у вас есть вся отладочная информация (которая обычно удаляется).

Затем вы можете перейти к so или pyd и использовать инструменты, специфичные для платформы, чтобы извлечьотладочная информация (хранится в so или pdb в Windows) для требуемой функции.Возможно, вы захотите взглянуть на информацию DWARF для Linux (в Windows документация AFAIK отсутствует).

0 голосов
/ 26 октября 2018

Нет, нет.В Python нет доступных метаданных, которые позволили бы вам найти исходный файл.Такие метаданные должны создаваться явным образом разработчиками Python без явного преимущества в отношении того, чего это может достичь.

Прежде всего, подавляющее большинство установок Python не включают исходный код на языке Си.Далее, хотя можно было ожидать, что пользователи языка Python смогут читать исходный код Python, база пользователей Python очень широка, и многие не знают C или не заинтересованы в том, как работает код C, и, наконец, даже разработчики, которыезнаю, что нельзя ожидать, что C прочитает документацию API Python C , что быстро становится требованием, если вы хотите понять кодовую базу Python.

Файлы C не отображаются напрямуюв конкретный выходной файл, в отличие от файлов и сценариев кэширования байт-кода Python.Если вы не создадите отладочную сборку с таблицей символов, компилятор не сохранит имя исходного файла в сгенерированном объектном файле (.o), который он выводит, и компоновщик не запишет, какие файлы .o были включены в полученный результат.Также не все C-файлы вносят свой вклад в один и тот же исполняемый или динамический общий объектный файл;некоторые становятся частью двоичного файла Python, другие становятся загружаемыми расширениями, и смесь настраивается и зависит от того, какие внешние библиотеки доступны во время компиляции.

А между макрофайлами, setup.py и макросами препропрессора C, комбинация входных файлов и то, какие строки исходного кода фактически используются для создания каждого из выходных файлов, также различается.И последнее, но не менее важное: поскольку исходные файлы C больше не используются во время выполнения, нельзя ожидать, что они по-прежнему будут доступны в том же исходном местоположении, поэтому даже если были сохранены некоторые метаданные, вы все равно не сможете отобразить их обратно.оригинал.

Итак, просто проще просто запомнить несколько базовых правил о том, как работает Python C-API, а затем отобразить это обратно в код C с помощью нескольких поисковых запросов кода..

Либо загрузите исходный код Python и создайте отладочную сборку, а также используйте хорошую среду IDE, чтобы помочь сопоставить символы и тому подобное с исходными файлами.Различные компиляторы, платформы и IDE имеют разные методы поддержки таблиц символов для отладки.

...