From ed55769e937d051fe97dc3cdf1be9f3e2f2dbe48 Mon Sep 17 00:00:00 2001 From: Phil Thompson Date: Mon, 2 Dec 2024 17:51:21 +0000 Subject: [PATCH] Snapshot regression The resolution of issue #8 raised exceptions in the resolver and generated bad code. Other cosmetic changes to the code and documentation were made. --- docs/annotations.rst | 17 +++++++-------- sipbuild/generator/outputs/code/code.py | 20 ++++++++--------- sipbuild/generator/parser/parser_manager.py | 4 ++-- sipbuild/generator/resolver/resolver.py | 24 +++++++++------------ sipbuild/generator/utils.py | 3 ++- sipbuild/module/source/12/sip.h.in | 3 ++- sipbuild/module/source/13/sip.h.in | 3 ++- 7 files changed, 36 insertions(+), 38 deletions(-) diff --git a/docs/annotations.rst b/docs/annotations.rst index d8ab25ef..a2268706 100644 --- a/docs/annotations.rst +++ b/docs/annotations.rst @@ -398,11 +398,11 @@ Class Annotations .. class-annotation:: Deprecated - This string annotation is used to specify that the class is deprecated. - Deprecation message is optionnal and would be reported when a deprecation - warning is issued. - It is the equivalent of annotating all the class's constructors, function - and methods as being deprecated. + This optional string annotation is used to specify that the class is + deprecated. Any string is appended to the deprecation warning and is + usually used to suggest an appropriate alternative. It is the equivalent + of annotating all the class's constructors, function and methods as being + deprecated. .. class-annotation:: FileExtension @@ -713,10 +713,9 @@ Function Annotations .. function-annotation:: Deprecated - This string annotation is used to specify that the constructor or function - is deprecated. A deprecation warning is issued whenever the constructor or - function is called. Deprecation message is optionnal and would be reported - when a deprecation warning is issued. + This optional string annotation is used to specify that the constructor or + function is deprecated. Any string is appended to the deprecation warning + and is usually used to suggest an appropriate alternative. .. function-annotation:: DisallowNone diff --git a/sipbuild/generator/outputs/code/code.py b/sipbuild/generator/outputs/code/code.py index 5d487b42..fabe04de 100644 --- a/sipbuild/generator/outputs/code/code.py +++ b/sipbuild/generator/outputs/code/code.py @@ -17,8 +17,8 @@ ArrayArgument, CodeBlock, DocstringSignature, GILAction, IfaceFileType, KwArgs, MappedType, PyQtMethodSpecifier, PySlot, QualifierType, Transfer, ValueType, WrappedClass, WrappedEnum) -from ...utils import (find_method, py_as_int, same_signature, abi_version_check, - abi_has_deprecated_message) +from ...utils import (abi_has_deprecated_message, abi_version_check, + find_method, py_as_int, same_signature) from ..formatters import (fmt_argument_as_cpp_type, fmt_argument_as_name, fmt_class_as_scoped_name, fmt_copying, fmt_enum_as_cpp_type, @@ -6269,12 +6269,12 @@ def _constructor_call(sf, spec, bindings, klass, ctor, error_flag, # Note that any temporaries will leak if an exception is raised. if abi_has_deprecated_message(spec): - str_deprecated_message = f'''"{ctor.deprecated}"''' if ctor.deprecated else "NULL" - sf.write(f' if (sipDeprecated({_cached_name_ref(klass.py_name)}, SIP_NULLPTR, {str_deprecated_message}) < 0)') + str_deprecated_message = f'"{ctor.deprecated}"' if ctor.deprecated else 'SIP_NULLPTR' + sf.write(f' if (sipDeprecated({_cached_name_ref(klass.py_name)}, SIP_NULLPTR, {str_deprecated_message}) < 0)\n') else: - sf.write(f' if (sipDeprecated({_cached_name_ref(klass.py_name)}, SIP_NULLPTR) < 0)') + sf.write(f' if (sipDeprecated({_cached_name_ref(klass.py_name)}, SIP_NULLPTR) < 0)\n') - sf.write(f' return SIP_NULLPTR;') + sf.write(f' return SIP_NULLPTR;\n\n') # Call any pre-hook. if ctor.prehook is not None: @@ -7110,12 +7110,12 @@ def _function_call(sf, spec, bindings, scope, overload, dereferenced, # Note that any temporaries will leak if an exception is raised. if abi_has_deprecated_message(spec): - str_deprecated_message = f'''"{overload.deprecated}"''' if overload.deprecated else "NULL" - sf.write(f' if (sipDeprecated({scope_py_name_ref}, {_cached_name_ref(overload.common.py_name)}, {str_deprecated_message}) < 0)') + str_deprecated_message = f'"{overload.deprecated}"' if overload.deprecated else 'SIP_NULLPTR' + sf.write(f' if (sipDeprecated({scope_py_name_ref}, {_cached_name_ref(overload.common.py_name)}, {str_deprecated_message}) < 0)\n') else: - sf.write(f' if (sipDeprecated({scope_py_name_ref}, {_cached_name_ref(overload.common.py_name)}) < 0)') + sf.write(f' if (sipDeprecated({scope_py_name_ref}, {_cached_name_ref(overload.common.py_name)}) < 0)\n') - sf.write(f' return {error_return};') + sf.write(f' return {error_return};\n\n') # Call any pre-hook. if overload.prehook is not None: diff --git a/sipbuild/generator/parser/parser_manager.py b/sipbuild/generator/parser/parser_manager.py index 3f98af5c..d50f0f69 100644 --- a/sipbuild/generator/parser/parser_manager.py +++ b/sipbuild/generator/parser/parser_manager.py @@ -21,8 +21,8 @@ SourceLocation, Specification, Transfer, TypeHints, WrappedClass, WrappedException, WrappedEnum, WrappedEnumMember) from ..templates import encoded_template_name, same_template_signature -from ..utils import (argument_as_str, cached_name, find_iface_file, - normalised_scoped_name, same_base_type, abi_has_deprecated_message) +from ..utils import (abi_has_deprecated_message, argument_as_str, cached_name, + find_iface_file, normalised_scoped_name, same_base_type) from . import rules from . import tokens diff --git a/sipbuild/generator/resolver/resolver.py b/sipbuild/generator/resolver/resolver.py index 54064d53..71690fd5 100644 --- a/sipbuild/generator/resolver/resolver.py +++ b/sipbuild/generator/resolver/resolver.py @@ -649,8 +649,8 @@ def _set_mro(spec, klass, error_log, seen=None): if klass.scope is not None: _set_mro(spec, klass.scope, error_log, seen=seen) - if klass.scope.deprecated and not klass.deprecated : - klass.deprecated = klass.scope.deprecated + if klass.scope.deprecated: + klass.deprecated = True if klass.iface_file.type is IfaceFileType.CLASS: # The first thing is itself. @@ -687,11 +687,8 @@ def _set_mro(spec, klass, error_log, seen=None): if klass.iface_file.module is spec.module: superklass_mro.iface_file.needed = True - if scope.deprecated and not overload.deprecated : - overload.deprecated = scope.deprecated - - if superklass_mro.deprecated and not klass.deprecated: - klass.deprecated = superklass_mro.deprecated + if superklass_mro.deprecated: + klass.deprecated = True # If the super-class is a QObject sub-class then this one is as # well. @@ -819,8 +816,8 @@ def _resolve_ctors(spec, klass, error_log): klass.iface_file.fq_cpp_name)) break - if klass.deprecated and not ctor.deprecated : - ctor.deprecated = klass.deprecated + if klass.deprecated: + ctor.deprecated = True def _transform_casts(spec, klass, error_log): @@ -876,8 +873,8 @@ def _add_default_copy_ctor(klass): ctor = Constructor(AccessSpecifier.PUBLIC, py_signature=signature, cpp_signature=signature) - if klass.deprecated and not ctor.deprecated : - ctor.deprecated = klass.deprecated + if klass.deprecated: + ctor.deprecated = True if not klass.is_abstract: klass.can_create = True @@ -922,9 +919,8 @@ def _resolve_scope_overloads(spec, overloads, error_log, final_checks, break if isinstance(scope, WrappedClass): - - if scope.deprecated and not overload.deprecated : - overload.deprecated = scope.deprecated + if scope.deprecated: + overload.deprecated = True if overload.is_abstract: scope.is_abstract = True diff --git a/sipbuild/generator/utils.py b/sipbuild/generator/utils.py index 960bb9e0..04d1cdcf 100644 --- a/sipbuild/generator/utils.py +++ b/sipbuild/generator/utils.py @@ -492,7 +492,8 @@ def abi_version_check(spec, min_12, min_13): return spec.abi_version >= min_13 or (min_12 <= spec.abi_version < (13, 0)) + def abi_has_deprecated_message(spec): - """ Return True if the ABI implements sipDeprecated() with message. """ + """ Return True if the ABI implements sipDeprecated() with a message. """ return abi_version_check(spec, (12, 16), (13, 9)) diff --git a/sipbuild/module/source/12/sip.h.in b/sipbuild/module/source/12/sip.h.in index 81cf79f5..4ff7695f 100644 --- a/sipbuild/module/source/12/sip.h.in +++ b/sipbuild/module/source/12/sip.h.in @@ -44,7 +44,8 @@ extern "C" { * * v12.16 * - Python v3.9 or later is required. - * - Add the possibility to define a message to Deprecated annotation and generate @deprecated macro in pyi files + * - Added a new implementation of sipDeprecated() that takes an optional + * supplementary message. * * v12.15 * - Added the 'I' conversion character to the argument and result parsers. diff --git a/sipbuild/module/source/13/sip.h.in b/sipbuild/module/source/13/sip.h.in index de18a330..4cfbb246 100644 --- a/sipbuild/module/source/13/sip.h.in +++ b/sipbuild/module/source/13/sip.h.in @@ -44,7 +44,8 @@ extern "C" { * * v13.9 * - Python v3.9 or later is required. - * - Add the possibility to define a message to Deprecated annotation and generate @deprecated macro in pyi files + * - Added a new implementation of sipDeprecated() that takes an optional + * supplementary message. * * v13.8 * - Added the 'I' conversion character to the argument and result parsers.