Skip to content

Commit

Permalink
Merge branch 'hotfix/2.6.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
kayhayen committed Jan 30, 2025
2 parents 0fbce78 + fefcbdf commit 6d2eb8f
Show file tree
Hide file tree
Showing 17 changed files with 367 additions and 138 deletions.
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
nuitka (2.6.2+ds-1) unstable; urgency=medium

* New upstream hotfix release.

-- Kay Hayen <kay.hayen@gmail.com> Wed, 29 Jan 2025 19:15:01 +0100

nuitka (2.6.1+ds-1) unstable; urgency=medium

* New upstream hotfix release.
Expand Down
18 changes: 18 additions & 0 deletions misc/nuitka-package-config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,24 @@
"type": "string"
}
},
"global_replacements_re": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"global_replacements": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"global_replacements_plain": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"replacements_re": {
"type": "object",
"additionalProperties": {
Expand Down
17 changes: 14 additions & 3 deletions nuitka/BytecodeCaching.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from nuitka.containers.OrderedSets import OrderedSet
from nuitka.importing.Importing import locateModule, makeModuleUsageAttempt
from nuitka.ModuleRegistry import getModuleOptimizationTimingInfos
from nuitka.plugins.Plugins import Plugins
from nuitka.utils.AppDirs import getCacheDir
from nuitka.utils.FileOperations import makePath
Expand Down Expand Up @@ -50,7 +51,7 @@ def hasCachedImportedModuleUsageAttempts(module_name, source_code, source_ref):


# Bump this is format is changed or enhanced implementation might different ones.
_cache_format_version = 6
_cache_format_version = 7


def getCachedImportedModuleUsageAttempts(module_name, source_code, source_ref):
Expand Down Expand Up @@ -118,11 +119,20 @@ def getCachedImportedModuleUsageAttempts(module_name, source_code, source_ref):
# something changed there.
pass

return result
# The Json doesn't store integer keys.
for pass_timing_info in data["timing_infos"]:
pass_timing_info[3] = dict(
(int(key), value) for (key, value) in pass_timing_info[3].items()
)

return result, data["timing_infos"]


def writeImportedModulesNamesToCache(
module_name, source_code, used_modules, distribution_names
module_name,
source_code,
used_modules,
distribution_names,
):
cache_name = makeCacheName(module_name, source_code)
cache_filename = _getCacheFilename(cache_name, "json")
Expand All @@ -138,6 +148,7 @@ def writeImportedModulesNamesToCache(
# We use a tuple, so preserve the order.
"modules_used": used_modules,
"distribution_names": distribution_names,
"timing_infos": getModuleOptimizationTimingInfos(module_name),
}

makePath(os.path.dirname(cache_filename))
Expand Down
21 changes: 18 additions & 3 deletions nuitka/ModuleRegistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import collections
import os

from nuitka.containers.Namedtuples import makeNamedtupleClass
from nuitka.containers.OrderedSets import OrderedSet
from nuitka.PythonVersions import python_version

Expand Down Expand Up @@ -234,15 +235,15 @@ def addModuleInfluencingCondition(


def addModuleInfluencingVariable(
module_name, plugin_name, variable_name, control_tags, result
module_name, config_module_name, plugin_name, variable_name, control_tags, result
):
if module_name not in module_influencing_plugins:
module_influencing_plugins[module_name] = OrderedSet()
module_influencing_plugins[module_name].add(
(
plugin_name,
"variable-used",
(variable_name, tuple(control_tags), repr(result)),
(variable_name, tuple(control_tags), repr(result), config_module_name),
)
)

Expand Down Expand Up @@ -278,7 +279,8 @@ def getModuleInfluences(module_name):
# Information about how long the optimization took.
module_timing_infos = {}

ModuleOptimizationTimingInfo = collections.namedtuple(

ModuleOptimizationTimingInfo = makeNamedtupleClass(
"ModuleOptimizationTimingInfo",
("pass_number", "time_used", "micro_passes", "merge_counts"),
)
Expand All @@ -288,6 +290,13 @@ def addModuleOptimizationTimeInformation(
module_name, pass_number, time_used, micro_passes, merge_counts
):
module_timing_info = list(module_timing_infos.get(module_name, []))

# Do not record cached bytecode loaded timing information, not useful
# and duplicate, we want the original values.
if pass_number == 1 and len(module_timing_info) == 1:
assert micro_passes == 0
return

module_timing_info.append(
ModuleOptimizationTimingInfo(
pass_number=pass_number,
Expand All @@ -303,6 +312,12 @@ def getModuleOptimizationTimingInfos(module_name):
return module_timing_infos.get(module_name, ())


def setModuleOptimizationTimingInfos(module_name, timing_infos):
module_timing_infos[module_name] = [
ModuleOptimizationTimingInfo(*timing_info) for timing_info in timing_infos
]


def getImportedModuleNames():
result = OrderedSet()

Expand Down
2 changes: 1 addition & 1 deletion nuitka/Version.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"""

version_string = """\
Nuitka V2.6.1
Nuitka V2.6.2
Copyright (C) 2025 Kay Hayen."""


Expand Down
4 changes: 2 additions & 2 deletions nuitka/build/SconsInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def _createSconsDebugScript(source_dir, scons_command):
exit_code = subprocess.call(
%(scons_command)r,
env={%(env)s}
env={%(env)s},
shell=False
)"""
% {
Expand Down Expand Up @@ -339,7 +339,7 @@ def _createSconsDebugScript(source_dir, scons_command):
contents="""\
%(script_prelude)s
'%(scons_python)s' '%(scons_debug_script_name)s'
"%(scons_python)s" "%(scons_debug_script_name)s"
"""
% {
"script_prelude": script_prelude,
Expand Down
2 changes: 1 addition & 1 deletion nuitka/build/include/nuitka/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ NUITKA_MAY_BE_UNUSED static bool _CHECK_AND_CLEAR_EXCEPTION_OCCURRED(PyThreadSta
Equivalent to if(PyErr_ExceptionMatches(PyExc_StopIteration) PyErr_Clear();
If error is raised by built-in function next() and an iterators __next__()
If error is raised by built-in function next() and an iterator's __next__()
method to signal that there are no further items produced by the iterator then
it resets the TSTATE to NULL and returns True else return False
Expand Down
7 changes: 6 additions & 1 deletion nuitka/build/static_src/MetaPathBasedLoader.c
Original file line number Diff line number Diff line change
Expand Up @@ -2049,8 +2049,13 @@ void registerMetaPathBasedLoader(struct Nuitka_MetaPathBasedLoaderEntry *_loader

global_loader);

// Our "sys.path_hooks" entry uses "os.path" to compare filenames, so we need
// to load it without.
PyThreadState *tstate = PyThreadState_GET();
IMPORT_HARD_OS_PATH(tstate);

// Register it as a sys.path_hook
LIST_APPEND1(Nuitka_SysGetObject("path_hooks"), PyObject_GetAttrString(global_loader, "sys_path_hook"));
LIST_INSERT_CONST(Nuitka_SysGetObject("path_hooks"), 0, PyObject_GetAttrString(global_loader, "sys_path_hook"));
}

#if defined(_NUITKA_STANDALONE)
Expand Down
2 changes: 1 addition & 1 deletion nuitka/freezer/IncludedDataFiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,8 @@ def addIncludedDataFile(included_datafile):
) or isFilenameBelowPath(
path=external_datafile_pattern, filename=included_datafile.dest_path
):
included_datafile.tags.clear()
included_datafile.tags.add("inhibit")
included_datafile.tags.remove("copy")

return

Expand Down
72 changes: 60 additions & 12 deletions nuitka/plugins/PluginBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -1435,7 +1435,8 @@ def evaluateExpressionOrConstant(
):
if self.isValueForEvaluation(expression):
return self.evaluateExpression(
full_name=full_name,
config_module_name=full_name,
module_name=full_name,
expression=expression,
config_name=config_name,
extra_context=extra_context,
Expand All @@ -1456,6 +1457,8 @@ def getExpressionConstants(self, full_name):
if declarations and self.evaluateCondition(
full_name=full_name,
condition=constant_config.get("when", "True"),
allow_constants=False,
allow_variables=False,
):
for constant_name, constant_value in declarations.items():
constants[constant_name] = self.evaluateExpressionOrConstant(
Expand Down Expand Up @@ -1492,6 +1495,8 @@ def getExpressionVariables(self, full_name):
if self.evaluateCondition(
full_name=full_name,
condition=variable_config.get("when", "True"),
allow_constants=True,
allow_variables=False,
):
setup_codes.extend(
"%s=%r" % (constant_name, constant_value)
Expand Down Expand Up @@ -1534,19 +1539,28 @@ def getExpressionVariables(self, full_name):
return _module_config_variables[full_name]

def evaluateExpression(
self, full_name, expression, config_name, extra_context, single_value
self,
config_module_name,
module_name,
expression,
config_name,
extra_context,
single_value,
):
context = _makeEvaluationContext(
logger=self, full_name=full_name, config_name=config_name
logger=self, full_name=config_module_name, config_name=config_name
)

def get_variable(variable_name):
assert type(variable_name) is str, variable_name

result = self.getExpressionVariables(full_name=full_name)[variable_name]
result = self.getExpressionVariables(full_name=config_module_name)[
variable_name
]

addModuleInfluencingVariable(
module_name=full_name,
module_name=module_name,
config_module_name=config_module_name,
plugin_name=self.plugin_name,
variable_name=variable_name,
control_tags=context.used_tags,
Expand All @@ -1558,7 +1572,9 @@ def get_variable(variable_name):
def get_constant(constant_name):
assert type(constant_name) is str, constant_name

result = self.getExpressionConstants(full_name=full_name)[constant_name]
result = self.getExpressionConstants(full_name=config_module_name)[
constant_name
]

# TODO: Record the constant value in report.

Expand All @@ -1568,13 +1584,13 @@ def get_constant(constant_name):
context["get_constant"] = get_constant

def get_parameter(parameter_name, default):
result = Options.getModuleParameter(full_name, parameter_name)
result = Options.getModuleParameter(config_module_name, parameter_name)

if result is None:
result = default

self.addModuleInfluencingParameter(
module_name=full_name,
module_name=config_module_name,
parameter_name=parameter_name,
condition_tags_used=context.used_tags,
result=result,
Expand Down Expand Up @@ -1603,16 +1619,16 @@ def get_parameter(parameter_name, default):
if type(result) not in (str, unicode):
if single_value:
self._checkStrResult(
value=result, expression=expression, full_name=full_name
value=result, expression=expression, full_name=config_module_name
)
else:
self._checkSequenceResult(
value=result, expression=expression, full_name=full_name
value=result, expression=expression, full_name=config_module_name
)

for v in result:
self._checkStrResult(
value=v, expression=expression, full_name=full_name
value=v, expression=expression, full_name=config_module_name
)

# Make it immutable in case it's a list.
Expand All @@ -1636,7 +1652,9 @@ def _checkSequenceResult(self, value, expression, full_name):
% (expression, full_name)
)

def evaluateCondition(self, full_name, condition):
def evaluateCondition(
self, full_name, condition, allow_constants=True, allow_variables=True
):
# Note: Caching makes no sense yet, this should all be very fast and
# cache themselves. TODO: Allow plugins to contribute their own control
# tag values during creation and during certain actions.
Expand All @@ -1650,6 +1668,36 @@ def evaluateCondition(self, full_name, condition):
logger=self, full_name=full_name, config_name="'when' configuration"
)

def get_variable(variable_name):
assert type(variable_name) is str, variable_name

result = self.getExpressionVariables(full_name=full_name)[variable_name]

addModuleInfluencingVariable(
module_name=full_name,
config_module_name=full_name,
plugin_name=self.plugin_name,
variable_name=variable_name,
control_tags=context.used_tags,
result=result,
)

return result

def get_constant(constant_name):
assert type(constant_name) is str, constant_name

result = self.getExpressionConstants(full_name=full_name)[constant_name]

# TODO: Record the constant value in report.

return result

if allow_constants:
context["get_constant"] = get_constant
if allow_variables:
context["get_variable"] = get_variable

def get_parameter(parameter_name, default):
result = Options.getModuleParameter(full_name, parameter_name)

Expand Down
Loading

0 comments on commit 6d2eb8f

Please sign in to comment.