Как вызвать глобальную функцию SCons из вспомогательного скрипта, вызываемого SConscript?

У меня есть некоторая нетривиальная логика, необходимая для вычисления путей к определенным каталогам исходных файлов и файлов заголовков, и, поскольку она применяется к нескольким SConscripts, я помещаю ее в отдельный файл .py, импортированный из каждого SConscript, который в ней нуждается. Теперь мне нужно иметь возможность вызывать глобальную функцию SCons (в данном случае функцию Glob) из вспомогательного сценария. Раньше эту функцию можно было вызывать непосредственно из SConscripts, но теперь, когда мне нужно вызвать ее из отдельного вспомогательного сценария, я не могу понять, как ее вызвать. Я полагаю, что это, вероятно, тривиально, но я действительно не очень хорошо знаком с Python.

ОБНОВЛЕНИЕ:
Похоже, что возможность вызывать Glob() как «глобальную функцию» как-то связана с некоторыми трюками, которые использует SCons. Вот выдержка из основного входного файла (SConscript.py, который не совпадает с SConscripts, которые мы приправляем по всему нашему исходному дереву):

_DefaultEnvironmentProxy = None

def get_DefaultEnvironmentProxy():
    global _DefaultEnvironmentProxy
    if not _DefaultEnvironmentProxy:
        default_env = SCons.Defaults.DefaultEnvironment()
        _DefaultEnvironmentProxy = SCons.Environment.NoSubstitutionProxy(default_env)
    return _DefaultEnvironmentProxy

class DefaultEnvironmentCall(object):
    """A class that implements "global function" calls of
    Environment methods by fetching the specified method from the
    DefaultEnvironment's class.  Note that this uses an intermediate
    proxy class instead of calling the DefaultEnvironment method
    directly so that the proxy can override the subst() method and
    thereby prevent expansion of construction variables (since from
    the user's point of view this was called as a global function,
    with no associated construction environment)."""
    def __init__(self, method_name, subst=0):
        self.method_name = method_name
        if subst:
            self.factory = SCons.Defaults.DefaultEnvironment
        else:
            self.factory = get_DefaultEnvironmentProxy
    def __call__(self, *args, **kw):
        env = self.factory()
        method = getattr(env, self.method_name)
        return method(*args, **kw)


def BuildDefaultGlobals():
    """
    Create a dictionary containing all the default globals for
    SConstruct and SConscript files.
    """

    global GlobalDict
    if GlobalDict is None:
        GlobalDict = {}

        import SCons.Script #     <-------This is referring to a directory with a file named __init__.py, which I've learned is something special in Python
        d = SCons.Script.__dict__
        def not_a_module(m, d=d, mtype=type(SCons.Script)):
             return not isinstance(d[m], mtype)
        for m in filter(not_a_module, dir(SCons.Script)):
             GlobalDict[m] = d[m]

    return GlobalDict.copy()

Поэтому я подумал, что, возможно, мне нужно import SCons.Script в моем вспомогательном скрипте:

import SCons.Script

К сожалению, я все еще получаю это:

NameError: name 'Glob' is not defined:
  File "D:\Git\......\SConstruct", line 412:
    SConscript(theSconscript, duplicate=0)
  File "c:\python37\lib\site-packages\scons\SCons\Script\SConscript.py", line 671:
    return method(*args, **kw)
  File "c:\python37\lib\site-packages\scons\SCons\Script\SConscript.py", line 608:
    return _SConscript(self.fs, *files, **subst_kw)
  .
  .
  .
  File "D:\Git\........\SConscript", line 433:
  .
  .
  .
  File "D:\Git\............\PathSelector.py", line 78:
    src_files.extend(Glob((os.path.join(src_path_a, '*.c')), strings=1))
Покажите нам вспомогательный скрипт и определение функции Glob. Детали имеют значение. Как вы импортируете эту функцию? Мы будем заботиться о переменной окружения PYTHONPATH (она должна содержать точку . для текущего рабочего каталога), и мы будем заботиться о os.getcwd(). Если у вас есть трассировка стека, возможно, из-за неудачного import, укажите полную трассировку в своем вопросе. При отслеживании ошибок импорта вы можете обнаружить, что $ python -m site предлагает полезные диагностические данные.
J_H 10.01.2023 22:04

@J_H Спасибо, что предложили помощь; мое обновление выше предоставляет достаточно информации?

phonetagger 10.01.2023 22:49

Хм, это много одиночных шагов, не знаю, что с этим делать. Иногда l (список), p variable, b break_line и c (продолжение) хороши для краткого пропуска дюжины «скучных» строк кода, которые, как известно, хорошо работают. // Не стесняйтесь вызывать встроенный glob напрямую, если вам не нужна прокладка. Теперь давайте попробуем сфокусировать этот вопрос таким образом, чтобы участники SO могли помочь, используя стандартный шаблон: я набрал команду, я увидел это, я надеялся увидеть это.

J_H 10.01.2023 23:23

SCons делает некоторые трюки, чтобы удалить шаблонную пластину, где это возможно, но, насколько мне известно, даже если Glob выглядит как глобальная функция, под капотом SCons по-прежнему вызывает ее для объекта среды по умолчанию. Нет особого смысла пытаться воспроизвести эти трюки в файле *.py. Просто передайте ему среду. Возможно, я мог бы рассказать больше, если бы вы предоставили свой код и ошибку, которую вы получаете. Это было бы намного полезнее, чем выдержки из исходников SCons.

Piotr Siupa 11.01.2023 09:55

@PiotrSiupa Как мне передать среду SCons в мой код вспомогательного скрипта? Извините, может быть, это очевидно для программиста Python, но я не слишком хорошо знаком с Python.

phonetagger 11.01.2023 15:50
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из справочной страницы:

Глобальные функции можно вызывать из пользовательских модулей Python, которые вы импортируете в файл SConscript, добавляя следующий импорт в модуль Python:

from SCons.Script import *

Ух ты. Спасибо, что прочитали руководство для меня. -я с красным лицом-

phonetagger 11.01.2023 16:45

Не беспокойтесь об этом... это БОЛЬШАЯ справочная страница.

Mats Wichmann 12.01.2023 02:00

Другие вопросы по теме