[neon/forks/sip6/Neon/release] debian: Backport upstream patch to fix handling of composite classes.
Dmitry Shachnev
null at kde.org
Sat Feb 4 02:04:46 GMT 2023
Git commit 37b2bd4bb8d249ddae6db1c8ca804fc7036a8f2c by Dmitry Shachnev.
Committed on 02/02/2023 at 09:08.
Pushed by carlosdem into branch 'Neon/release'.
Backport upstream patch to fix handling of composite classes.
Closes: #1030188.
M +7 -0 debian/changelog
A +471 -0 debian/patches/composite_classes.diff
M +1 -0 debian/patches/series
https://invent.kde.org/neon/forks/sip6/commit/37b2bd4bb8d249ddae6db1c8ca804fc7036a8f2c
diff --git a/debian/changelog b/debian/changelog
index 2153ecd..53eceb6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+sip6 (6.7.6+dfsg-2) UNRELEASED; urgency=medium
+
+ * Backport upstream patch to fix handling of composite classes
+ (closes: #1030188).
+
+ -- Dmitry Shachnev <mitya57 at debian.org> Thu, 02 Feb 2023 13:07:19 +0400
+
sip6 (6.7.6+dfsg-1) unstable; urgency=medium
* New upstream release.
diff --git a/debian/patches/composite_classes.diff b/debian/patches/composite_classes.diff
new file mode 100644
index 0000000..f28f527
--- /dev/null
+++ b/debian/patches/composite_classes.diff
@@ -0,0 +1,471 @@
+From: Phil Thompson <phil at riverbankcomputing.com>
+Date: Tue, 31 Jan 2023 16:59:37 +0000
+Subject: Refactored the handling of composite classes so that they are
+ populated properly.
+
+Origin: upstream, https://riverbankcomputing.com/hg/sip/rev/0afab92347b6
+---
+ code_generator/gencode.c | 22 ++-----
+ code_generator/py2c.c | 10 +---
+ code_generator/sip.h | 7 +--
+ sipbuild/bindings.py | 4 +-
+ sipbuild/generator/outputs/pyi.py | 4 +-
+ sipbuild/generator/parser/parser_manager.py | 90 +++++++++++++----------------
+ sipbuild/generator/parser/rules.py | 29 ++++------
+ sipbuild/generator/specification.py | 11 ++--
+ 8 files changed, 67 insertions(+), 110 deletions(-)
+
+diff --git a/code_generator/gencode.c b/code_generator/gencode.c
+index 9fc917c..ad83fa1 100644
+--- a/code_generator/gencode.c
++++ b/code_generator/gencode.c
+@@ -1,7 +1,7 @@
+ /*
+ * The code generator module for SIP.
+ *
+- * Copyright (c) 2022 Riverbank Computing Limited <info at riverbankcomputing.com>
++ * Copyright (c) 2023 Riverbank Computing Limited <info at riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+@@ -342,7 +342,7 @@ stringList *generateCode(sipSpec *pt, char *codeDir, const char *srcSuffix,
+ if (srcSuffix == NULL)
+ srcSuffix = (generating_c ? ".c" : ".cpp");
+
+- if (isComposite(pt->module))
++ if (pt->is_composite)
+ {
+ if (generateCompositeCpp(pt, codeDir, &generated, py_debug) < 0)
+ return NULL;
+@@ -1098,10 +1098,9 @@ static int generateCompositeCpp(sipSpec *pt, const char *codeDir,
+ );
+
+ for (mld = pt->module->allimports; mld != NULL; mld = mld->next)
+- if (mld->module->container == pt->module)
+- prcode(fp,
++ prcode(fp,
+ " sip_import_component_module(sipModuleDict, \"%s\");\n"
+- , mld->module->fullname->text);
++ , mld->module->fullname->text);
+
+ prcode(fp,
+ "\n"
+@@ -1229,8 +1228,7 @@ static const char *generateCpp(sipSpec *pt, moduleDef *mod,
+ );
+
+ /* Define the names. */
+- if (mod->container == NULL)
+- generateNameCache(pt, fp);
++ generateNameCache(pt, fp);
+
+ /* Generate the C++ code blocks. */
+ generateCppCodeBlock(mod->cppcode, fp);
+@@ -2047,15 +2045,7 @@ static const char *generateCpp(sipSpec *pt, moduleDef *mod,
+ , mname);
+
+ /* Generate the Python module initialisation function. */
+-
+- if (mod->container == pt->module)
+- prcode(fp,
+-"\n"
+-"PyObject *sip_init_%s()\n"
+-"{\n"
+- , mname);
+- else
+- generateModInitStart(pt->module, generating_c, fp);
++ generateModInitStart(pt->module, generating_c, fp);
+
+ /* Generate the global functions. */
+
+diff --git a/code_generator/py2c.c b/code_generator/py2c.c
+index 2e6b3f3..fc78fd8 100644
+--- a/code_generator/py2c.c
++++ b/code_generator/py2c.c
+@@ -2,7 +2,7 @@
+ * The transitional conversion from the output of the Python-based parser to
+ * that required by the rest of the C-based code generator.
+ *
+- * Copyright (c) 2022 Riverbank Computing Limited <info at riverbankcomputing.com>
++ * Copyright (c) 2023 Riverbank Computing Limited <info at riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+@@ -417,6 +417,7 @@ sipSpec *py2c(PyObject *spec, const char *encoding)
+ pt->exptypehintcode = codeblock_list_attr(spec, "exported_type_hint_code",
+ encoding);
+ pt->genc = bool_attr(spec, "c_bindings");
++ pt->is_composite = bool_attr(spec, "is_composite");
+ pt->plugins = str_list_attr(spec, "plugins", encoding);
+ pt->nrvirthandlers = int_attr(spec, "nr_virtual_handlers");
+ pt->qobject_cd = class_attr(pt, spec, "pyqt_qobject", encoding);
+@@ -1654,12 +1655,6 @@ static moduleDef *module(sipSpec *pt, PyObject *obj, const char *encoding)
+ if (bool_attr(obj, "has_delayed_dtors"))
+ setHasDelayedDtors(value);
+
+- if (bool_attr(obj, "is_composite"))
+- {
+- setIsComposite(value);
+- value->modflags &= ~MOD_SUPER_INIT_MASK;
+- }
+-
+ if (bool_attr(obj, "use_arg_names"))
+ setUseArgNames(value);
+
+@@ -1699,7 +1694,6 @@ static moduleDef *module(sipSpec *pt, PyObject *obj, const char *encoding)
+ value->next_key = int_attr(obj, "next_key");
+ value->license = license_attr(obj, "license", encoding);
+ value->proxies = class_list_attr(pt, obj, "proxies", encoding);
+- value->container = module_attr(pt, obj, "composite", encoding);
+ value->used = ifacefilelist_attr(pt, obj, "used", encoding);
+ value->imports = modulelist_attr(pt, obj, "imports", encoding);
+ value->allimports = modulelist_attr(pt, obj, "all_imports", encoding);
+diff --git a/code_generator/sip.h b/code_generator/sip.h
+index 23b3f49..cc427b0 100644
+--- a/code_generator/sip.h
++++ b/code_generator/sip.h
+@@ -1,7 +1,7 @@
+ /*
+ * The main header file for SIP.
+ *
+- * Copyright (c) 2022 Riverbank Computing Limited <info at riverbankcomputing.com>
++ * Copyright (c) 2023 Riverbank Computing Limited <info at riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+@@ -72,7 +72,6 @@
+
+ #define MOD_HAS_DELAYED_DTORS 0x0001 /* It has a class with a delayed dtor. */
+ #define MOD_IS_UNUSED 0x0002 /* This flag is unused. */
+-#define MOD_IS_COMPOSITE 0x0004 /* It is a composite module. */
+ #define MOD_IS_TRANSFORMED 0x0008 /* It's types have been transformed. */
+ #define MOD_USE_ARG_NAMES 0x0010 /* Use real argument names. */
+ #define MOD_USE_LIMITED_API 0x0020 /* Use the limited API. */
+@@ -85,8 +84,6 @@
+
+ #define hasDelayedDtors(m) ((m)->modflags & MOD_HAS_DELAYED_DTORS)
+ #define setHasDelayedDtors(m) ((m)->modflags |= MOD_HAS_DELAYED_DTORS)
+-#define isComposite(m) ((m)->modflags & MOD_IS_COMPOSITE)
+-#define setIsComposite(m) ((m)->modflags |= MOD_IS_COMPOSITE)
+ #define setIsTransformed(m) ((m)->modflags |= MOD_IS_TRANSFORMED)
+ #define isTransformed(m) ((m)->modflags & MOD_IS_TRANSFORMED)
+ #define setUseArgNames(m) ((m)->modflags |= MOD_USE_ARG_NAMES)
+@@ -954,7 +951,6 @@ typedef struct _moduleDef {
+ int next_key; /* The next key to allocate. */
+ licenseDef *license; /* The software license. */
+ struct _classDef *proxies; /* The list of proxy classes. */
+- struct _moduleDef *container; /* The container module, if any. */
+ struct _ifaceFileList *used; /* Interface files used. */
+ struct _moduleListDef *allimports; /* The list of all imports. */
+ struct _moduleListDef *imports; /* The list of direct imports. */
+@@ -1274,6 +1270,7 @@ typedef struct {
+ codeBlockList *exptypehintcode; /* Exported type hint code. */
+ classDef *qobject_cd; /* QObject class, NULL if none. */
+ int genc; /* Set if we are generating C code. */
++ int is_composite; /* Set if the main module is composite. */
+ struct _stringList *plugins; /* The list of plugins. */
+ struct _extractDef *extracts; /* The list of extracts. */
+ } sipSpec;
+diff --git a/sipbuild/bindings.py b/sipbuild/bindings.py
+index a2346c7..29758bd 100644
+--- a/sipbuild/bindings.py
++++ b/sipbuild/bindings.py
+@@ -1,4 +1,4 @@
+-# Copyright (c) 2022, Riverbank Computing Limited
++# Copyright (c) 2023, Riverbank Computing Limited
+ # All rights reserved.
+ #
+ # This copy of SIP is licensed for use under the terms of the SIP License
+@@ -175,7 +175,7 @@ class Bindings(Configurable):
+
+ module = spec.module
+
+- uses_limited_api = module.use_limited_api or module.is_composite
++ uses_limited_api = module.use_limited_api or spec.is_composite
+
+ # The details of things that will have been generated. Note that we
+ # don't include anything for .api files or generic extracts as the
+diff --git a/sipbuild/generator/outputs/pyi.py b/sipbuild/generator/outputs/pyi.py
+index b554366..0bf2972 100644
+--- a/sipbuild/generator/outputs/pyi.py
++++ b/sipbuild/generator/outputs/pyi.py
+@@ -1,4 +1,4 @@
+-# Copyright (c) 2022, Riverbank Computing Limited
++# Copyright (c) 2023, Riverbank Computing Limited
+ # All rights reserved.
+ #
+ # This copy of SIP is licensed for use under the terms of the SIP License
+@@ -49,7 +49,7 @@ f'''# The PEP 484 type hints stub file for the {module.py_name} module.
+
+ ''')
+
+- if module.is_composite:
++ if spec.is_composite:
+ _composite_module(pf, spec, module)
+ else:
+ _module(pf, spec, module)
+diff --git a/sipbuild/generator/parser/parser_manager.py b/sipbuild/generator/parser/parser_manager.py
+index 6608f75..b09504d 100644
+--- a/sipbuild/generator/parser/parser_manager.py
++++ b/sipbuild/generator/parser/parser_manager.py
+@@ -1,4 +1,4 @@
+-# Copyright (c) 2022, Riverbank Computing Limited
++# Copyright (c) 2023, Riverbank Computing Limited
+ # All rights reserved.
+ #
+ # This copy of SIP is licensed for use under the terms of the SIP License
+@@ -87,7 +87,6 @@ class ParserManager:
+ self.c_bindings = None
+ self.code_block = None
+ self.module_state = None
+- self.module_states = []
+ self.paren_depth = 0
+ self.parsing_template = False
+ self.parsing_virtual = False
+@@ -1205,14 +1204,9 @@ class ParserManager:
+ sip_file, raw_sip_file, input, lineno, lexpos, module_state = self._file_stack.pop()
+
+ if module_state is None:
++ self._import_module(self._sip_file)
+ module_state = self.module_state
+
+- # The current file was %Included so create a new Module and
+- # ModuleState as if it had been %Imported.
+- module = Module()
+- self.modules.append(module)
+- self.module_state = ModuleState(module, self._sip_file, self)
+-
+ self._file_stack.append(
+ (sip_file, raw_sip_file, input, lineno, lexpos, module_state))
+
+@@ -1459,9 +1453,7 @@ class ParserManager:
+ code will be generated for.
+ """
+
+- module = self.module_state.module
+-
+- return module is self.spec.module or module.composite is not None
++ return self.module_state.module is self.spec.module
+
+ def instantiate_class_template(self, p, symbol, fq_cpp_name, template,
+ py_name, no_type_name, docstring):
+@@ -1503,7 +1495,7 @@ class ParserManager:
+ raw_sip_file = sip_file
+ sip_file = os.path.abspath(sip_file)
+
+- self.module_state = ModuleState(self.spec.module, sip_file, self)
++ self.module_state = ModuleState(self.spec.module, sip_file)
+
+ try:
+ self._parser.parse(self._read(sip_file, raw_sip_file),
+@@ -1637,47 +1629,17 @@ class ParserManager:
+ "'{0}' is being read recursively".format(sip_file))
+ return
+
+- if new_module:
+- importing_from = self.module_state.module
+-
+- # Create a new module if it has not already been defined.
+- for module_state in self.module_states:
+- if module_state.sip_file == sip_file:
+- module = module_state.module
+- break
+- else:
+- module = Module()
+- self.modules.append(module)
+-
+- module.default_exception = self.module_state.module.default_exception
+- old_module_state = self.module_state
+- self.module_state = ModuleState(module, sip_file, self)
+-
+- # Get the configuration of the new module.
+- mod_tags, mod_disabled = get_bindings_configuration(
+- self.spec.abi_version[0], sip_file, self._include_dirs)
+-
+- for tag in mod_tags:
+- if tag not in self.tags:
+- self.tags.append(tag)
+-
+- for feature in mod_disabled:
+- if feature not in self._disabled_features:
+- self._disabled_features.append(feature)
++ # Ignore the file if we have already read it.
++ if sip_file in self._all_sip_files:
++ return
+
+- # Add the new import unless it has already been imported.
+- if module not in importing_from.imports:
+- importing_from.imports.insert(0, module)
++ if new_module:
++ old_module_state = self.module_state
++ self._import_module(sip_file)
+ else:
+ # This means that the file was %Included rather than %Imported.
+ old_module_state = None
+
+- # Ignore the file if we have already read it. This replicates the
+- # behaviour of the old parser but shouldn't be required for a well
+- # specified project.
+- if sip_file in self._all_sip_files:
+- return
+-
+ # Save the state of the current .sip file.
+ self._file_stack.append(
+ (self._sip_file, self.raw_sip_file, self._input,
+@@ -2116,6 +2078,34 @@ class ParserManager:
+ # call_super_init defaults to False if it wasn't specified.
+ module.call_super_init = bool(module_state.call_super_init)
+
++ def _import_module(self, sip_file):
++ """ Create a new Module object and corresponding ModuleState object for
++ a .sip file and make it current.
++ """
++
++ importing_from = self.module_state.module
++
++ module = Module()
++ self.modules.append(module)
++
++ module.default_exception = self.module_state.module.default_exception
++ self.module_state = ModuleState(module, sip_file)
++
++ # Get the configuration of the new module.
++ mod_tags, mod_disabled = get_bindings_configuration(
++ self.spec.abi_version[0], sip_file, self._include_dirs)
++
++ for tag in mod_tags:
++ if tag not in self.tags:
++ self.tags.append(tag)
++
++ for feature in mod_disabled:
++ if feature not in self._disabled_features:
++ self._disabled_features.append(feature)
++
++ # Add the new import.
++ importing_from.imports.append(module)
++
+ def _read(self, sip_file, raw_sip_file):
+ """ Return the contents of the current .sip file. """
+
+@@ -2149,7 +2139,7 @@ class ParserManager:
+ class ModuleState:
+ """ Encapsulate the parser-related state for a module. """
+
+- def __init__(self, module, sip_file, pm):
++ def __init__(self, module, sip_file):
+ """ Initialise the state. """
+
+ self.module = module
+@@ -2162,8 +2152,6 @@ class ModuleState:
+ self.kw_args = KwArgs.NONE
+ self.nr_timelines = 0
+
+- pm.module_states.append(self)
+-
+
+ class ScopeState:
+ """ Encapsulate the parser-related state for a scope. """
+diff --git a/sipbuild/generator/parser/rules.py b/sipbuild/generator/parser/rules.py
+index 0c3ad03..9c804e0 100644
+--- a/sipbuild/generator/parser/rules.py
++++ b/sipbuild/generator/parser/rules.py
+@@ -1,4 +1,4 @@
+-# Copyright (c) 2022, Riverbank Computing Limited
++# Copyright (c) 2023, Riverbank Computing Limited
+ # All rights reserved.
+ #
+ # This copy of SIP is licensed for use under the terms of the SIP License
+@@ -201,6 +201,12 @@ def p_composite_module(p):
+ if pm.skipping:
+ return
+
++ # A composite module must be the first one in the specification.
++ if not pm.in_main_module:
++ pm.parser_error(p, 1, "a %CompositeModule cannot be %Imported")
++
++ pm.spec.is_composite = True
++
+ if len(p) == 4:
+ name = p[2]
+ body = p[3]
+@@ -210,15 +216,7 @@ def p_composite_module(p):
+
+ module = pm.module_state.module
+
+- if module is not pm.modules[0]:
+- pm.parser_error(p, 1, "a %CompositeModule cannot be %Imported")
+-
+- if module.fq_py_name is not None:
+- pm.parser_error(p, 1,
+- "%CompositeModule must appear before any %Module directive")
+-
+ module.fq_py_name = cached_name(pm.spec, str(name))
+- module.is_composite = True
+
+ for directive in body:
+ if isinstance(directive, Docstring):
+@@ -1035,22 +1033,15 @@ def p_module(p):
+ if pm.skipping:
+ return
+
+- module_state = pm.module_state
+- module = module_state.module
+-
+ # See if this %Module is part of a %CompositeModule.
+- if module.is_composite or module.composite is not None:
++ if pm.spec.is_composite:
+ # Historically we %Include modules although conceptually we actually
+ # %Import them. Ensure that the scopes etc. are correct in either
+ # case.
+ pm.ensure_import()
+
+- # The module state may have changed.
+- module_state = pm.module_state
+-
+- module_state.module.composite = module if module.is_composite else module.composite
+-
+- module = module_state.module
++ module_state = pm.module_state
++ module = module_state.module
+
+ if module.fq_py_name is not None:
+ pm.parser_error(p, 1, "%Module has already been specified")
+diff --git a/sipbuild/generator/specification.py b/sipbuild/generator/specification.py
+index eecaaab..05a2dfb 100644
+--- a/sipbuild/generator/specification.py
++++ b/sipbuild/generator/specification.py
+@@ -1,4 +1,4 @@
+-# Copyright (c) 2022, Riverbank Computing Limited
++# Copyright (c) 2023, Riverbank Computing Limited
+ # All rights reserved.
+ #
+ # This copy of SIP is licensed for use under the terms of the SIP License
+@@ -979,9 +979,6 @@ class Module:
+ # Set if wrapped ctors should support cooperative multi-inheritance.
+ call_super_init: bool = False
+
+- # The containing composite module.
+- composite: Optional['Module'] = None
+-
+ # The text specified by any %Copying directives.
+ copying: List[CodeBlock] = field(default_factory=list)
+
+@@ -1023,9 +1020,6 @@ class Module:
+ # The code specified by any %InitialisationCode directives.
+ initialisation_code: List[CodeBlock] = field(default_factory=list)
+
+- # Set if the module is a composite module.
+- is_composite: bool = False
+-
+ # The software license.
+ license: Optional[License] = None
+
+@@ -1316,6 +1310,9 @@ class Specification:
+ # The interface files.
+ iface_files: List[IfaceFile] = field(default_factory=list)
+
++ # Set if the specification is for a composite module.
++ is_composite: bool = False
++
+ # The mapped type templates.
+ mapped_type_templates: List[MappedTypeTemplate] = field(default_factory=list)
+
diff --git a/debian/patches/series b/debian/patches/series
index 2792c84..1526b57 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +1,2 @@
intersphinx_local.diff
+composite_classes.diff
More information about the Neon-commits
mailing list