Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PyQGIS] Add message to /Deprecated/ annotations #59834

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -371,18 +371,21 @@ if(WITH_QSCIAPI)
set(_python ${Python_EXECUTABLE})
endif()

configure_file("${APIS_SRC_DIR}/generate_console_pap.py.in" ${CMAKE_BINARY_DIR}/generate_console_pap.py)
if (QSCI_SIP_DIR)
configure_file("${APIS_SRC_DIR}/generate_console_pap.py.in" ${CMAKE_BINARY_DIR}/generate_console_pap.py)

add_custom_command(
OUTPUT "${QGIS_PYTHON_PAP_FILE}"
DEPENDS "${QGIS_PYTHON_API_FILE}"
COMMAND ${_python} "${CMAKE_BINARY_DIR}/generate_console_pap.py" -platform offscreen "${QGIS_PYTHON_PAP_FILE}" "${APIS_SRC_DIR}" "${APIS_OUT_DIR}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Generating pap file for console auto-completion" VERBATIM)
add_custom_command(
OUTPUT "${QGIS_PYTHON_PAP_FILE}"
DEPENDS "${QGIS_PYTHON_API_FILE}"
COMMAND ${_python} "${CMAKE_BINARY_DIR}/generate_console_pap.py" -platform offscreen "${QGIS_PYTHON_PAP_FILE}" "${APIS_SRC_DIR}" "${APIS_OUT_DIR}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Generating pap file for console auto-completion" VERBATIM)

ADD_QGIS_RESOURCES("${APIS_OUT_DIR}" "python/qsci_apis" DEST_DATA_FILES "PyQGIS.api;PyQGIS.pap")
ADD_QGIS_RESOURCES("${APIS_OUT_DIR}" "python/qsci_apis" DEST_DATA_FILES "PyQGIS.api;PyQGIS.pap")

add_custom_target(pyqgis-pap ALL DEPENDS ${QGIS_PYTHON_API_FILE} ${QGIS_PYTHON_PAP_FILE} ${DEST_DATA_FILES})
endif()

add_custom_target(pyqgis-pap ALL DEPENDS ${QGIS_PYTHON_API_FILE} ${QGIS_PYTHON_PAP_FILE} ${DEST_DATA_FILES})
endif()

if(WITH_CUSTOM_WIDGETS)
Expand Down Expand Up @@ -463,4 +466,3 @@ foreach(module ${PY_MODULES})
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${module}/auto_generated DESTINATION ${SIP_DEFAULT_SIP_DIR}/qgis/${module})
endif()
endforeach(module)

Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ If ``color`` is an invalid color then the default icon color will be used.

virtual QWidget *paramWidget() /Factory,Deprecated/;

%Docstring

.. deprecated:: 3.20
%End
virtual bool hasDragEnabled() const;
virtual QgsMimeDataUtils::UriList mimeUris() const;

Expand Down Expand Up @@ -217,8 +221,6 @@ Browser parameter widget implementation for directory items.





/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
2 changes: 2 additions & 0 deletions python/PyQt6/core/auto_generated/geometry/qgsgeometry.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ Sets the underlying geometry store. Ownership of geometry is transferred.
.. seealso:: :py:func:`get`

.. seealso:: :py:func:`constGet`

.. deprecated:: 3.0
%End

bool isNull() const /HoldGIL/;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,14 @@ The caller takes responsibility for deleting the returned object.

virtual void paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget );


virtual int numberExportLayers() const /Deprecated/;

%Docstring

.. deprecated:: 3.10
%End

virtual void startLayeredExport();

virtual void stopLayeredExport();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@ Bilinear Raster Resampler
public:

QgsBilinearRasterResampler();

virtual void resample( const QImage &srcImage, QImage &dstImage ) /Deprecated/;

%Docstring

.. deprecated:: 3.12

Use :py:func:`~QgsBilinearRasterResampler.resampleV2` instead.
%End

virtual QImage resampleV2( const QImage &source, const QSize &size );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ Cubic Raster Resampler.

virtual QImage resampleV2( const QImage &source, const QSize &size );


virtual void resample( const QImage &srcImage, QImage &dstImage ) /Deprecated/;

%Docstring

.. deprecated:: 3.12

Use :py:func:`~QgsCubicRasterResampler.resampleV2` instead.
%End
virtual QString type() const;

virtual int tileBufferPixels() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ A scale bar style that draws text in the form of '1:XXXXX'.

virtual QSizeF calculateBoxSize( const QgsScaleBarSettings &settings, const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const /Deprecated/;

%Docstring

.. deprecated:: 3.14

Use the one with render context instead.
%End

};

Expand Down
6 changes: 4 additions & 2 deletions python/core/auto_generated/browser/qgsdirectoryitem.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ If ``color`` is an invalid color then the default icon color will be used.

virtual QWidget *paramWidget() /Factory,Deprecated/;

%Docstring

.. deprecated:: 3.20
%End
virtual bool hasDragEnabled() const;
virtual QgsMimeDataUtils::UriList mimeUris() const;

Expand Down Expand Up @@ -217,8 +221,6 @@ Browser parameter widget implementation for directory items.





/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
2 changes: 2 additions & 0 deletions python/core/auto_generated/geometry/qgsgeometry.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ Sets the underlying geometry store. Ownership of geometry is transferred.
.. seealso:: :py:func:`get`

.. seealso:: :py:func:`constGet`

.. deprecated:: 3.0
%End

bool isNull() const /HoldGIL/;
Expand Down
6 changes: 6 additions & 0 deletions python/core/auto_generated/layout/qgslayoutitemmap.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,14 @@ The caller takes responsibility for deleting the returned object.

virtual void paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget );


virtual int numberExportLayers() const /Deprecated/;

%Docstring

.. deprecated:: 3.10
%End

virtual void startLayeredExport();

virtual void stopLayeredExport();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@ Bilinear Raster Resampler
public:

QgsBilinearRasterResampler();

virtual void resample( const QImage &srcImage, QImage &dstImage ) /Deprecated/;

%Docstring

.. deprecated:: 3.12

Use :py:func:`~QgsBilinearRasterResampler.resampleV2` instead.
%End

virtual QImage resampleV2( const QImage &source, const QSize &size );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ Cubic Raster Resampler.

virtual QImage resampleV2( const QImage &source, const QSize &size );


virtual void resample( const QImage &srcImage, QImage &dstImage ) /Deprecated/;

%Docstring

.. deprecated:: 3.12

Use :py:func:`~QgsCubicRasterResampler.resampleV2` instead.
%End
virtual QString type() const;

virtual int tileBufferPixels() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ A scale bar style that draws text in the form of '1:XXXXX'.

virtual QSizeF calculateBoxSize( const QgsScaleBarSettings &settings, const QgsScaleBarRenderer::ScaleBarContext &scaleContext ) const /Deprecated/;

%Docstring

.. deprecated:: 3.14

Use the one with render context instead.
%End

};

Expand Down
5 changes: 4 additions & 1 deletion python/gui/gui.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ ${DEFAULTDOCSTRINGSIGNATURE}
%Import QtGui/QtGuimod.sip
%Import QtXml/QtXmlmod.sip
%Import QtMultimedia/QtMultimediamod.sip
%Import ${QSCI_SIP_MOD_NAME}

%If (HAVE_QSCI_SIP)
%Import ${QSCI_SIP_MOD_NAME}
%End

%Include gui_auto.sip
2 changes: 2 additions & 0 deletions python/gui/gui_auto.sip
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,9 @@
%Include auto_generated/editorwidgets/qgsdefaultsearchwidgetwrapper.sip
%Include auto_generated/editorwidgets/qgsdoublespinbox.sip
%Include auto_generated/editorwidgets/qgshtmlwidgetwrapper.sip
%If ( HAVE_QSCI_SIP )
%Include auto_generated/editorwidgets/qgsjsoneditwidget.sip
%End
%Include auto_generated/editorwidgets/qgsmultiedittoolbutton.sip
%Include auto_generated/editorwidgets/qgsrelationaggregatesearchwidgetwrapper.sip
%Include auto_generated/editorwidgets/qgsrelationreferencesearchwidgetwrapper.sip
Expand Down
40 changes: 35 additions & 5 deletions scripts/sipify.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ class MultiLineType(Enum):
parser = argparse.ArgumentParser(description="Convert header file to SIP and Python")
parser.add_argument("-debug", action="store_true", help="Enable debug mode")
parser.add_argument("-qt6", action="store_true", help="Enable Qt6 mode")
parser.add_argument(
"-generate_deprecated_message",
action="store_true",
help="Generate sip files with deprecated messages (supported only in SIP > 6.9.0)",
)
parser.add_argument("-sip_output", help="SIP output file")
parser.add_argument("-python_output", help="Python output file")
parser.add_argument("-class_map", help="Class map file")
Expand Down Expand Up @@ -79,7 +84,7 @@ def __init__(self):
self.debug: bool = False
self.is_qt6: bool = False
self.header_file: str = ""

self.generate_deprecated_message = False
self.current_line: str = ""
self.sip_run: bool = False
self.header_code: bool = False
Expand Down Expand Up @@ -127,6 +132,7 @@ def __init__(self):
self.static_methods = defaultdict(dict)
self.current_signal_args = []
self.signal_arguments = defaultdict(dict)
self.deprecated_message = None

def current_fully_qualified_class_name(self) -> str:
return ".".join(
Expand All @@ -145,6 +151,7 @@ def current_fully_qualified_struct_name(self) -> str:
CONTEXT = Context()
CONTEXT.debug = args.debug
CONTEXT.is_qt6 = args.qt6
CONTEXT.generate_deprecated_message = args.generate_deprecated_message
CONTEXT.header_file = args.headerfile
CONTEXT.input_lines = input_lines
CONTEXT.line_count = len(input_lines)
Expand Down Expand Up @@ -715,6 +722,14 @@ def create_class_links(line):
return line


def process_deprecated_message(message: str) -> str:
"""
Remove all doxygen specific command from deprecated message
"""
# SIP issue with ':' , see https://github.com/Python-SIP/sip/issues/59
return message.replace("\\see", "").replace(":", "")


def process_doxygen_line(line: str) -> str:
global CONTEXT

Expand Down Expand Up @@ -880,6 +895,9 @@ def process_doxygen_line(line: str) -> str:
version = version[:-1]
depr_line = f"\n.. deprecated:: {version}"
message = deprecated_match.group("DEPR_MESSAGE")
CONTEXT.deprecated_message = (
f"Since {version}. {process_deprecated_message(message)}"
)
if message:
depr_line += "\n"
depr_line += "\n".join(f"\n {_m}" for _m in message.split("\n"))
Expand Down Expand Up @@ -1157,14 +1175,20 @@ def fix_annotations(line):
CONTEXT.skipped_params_out.append(param)
dbg_info(f"caught removed param: {CONTEXT.skipped_params_out[-1]}")

if "SIP_DEPRECATED" in line:

if CONTEXT.deprecated_message is None:
exit_with_error(
f"Error in file {CONTEXT.header_file}: missing deprecated message for SIP_DEPRECATED instruction on line {CONTEXT.line_idx}. Please add \\deprecated instruction"
)

# Printed annotations
replacements = {
r"//\s*SIP_ABSTRACT\b": "/Abstract/",
r"\bSIP_ABSTRACT\b": "/Abstract/",
r"\bSIP_ALLOWNONE\b": "/AllowNone/",
r"\bSIP_ARRAY\b": "/Array/",
r"\bSIP_ARRAYSIZE\b": "/ArraySize/",
r"\bSIP_DEPRECATED\b": "/Deprecated/",
r"\bSIP_CONSTRAINED\b": "/Constrained/",
r"\bSIP_EXTERNAL\b": "/External/",
r"\bSIP_FACTORY\b": "/Factory/",
Expand All @@ -1190,15 +1214,21 @@ def fix_annotations(line):
# these have no effect (and aren't required) on sip >= 6
replacements[r"SIP_THROW\(\s*([\w\s,]+?)\s*\)"] = ""

if CONTEXT.generate_deprecated_message:
# check deprecated message is not empty
replacements[r"\bSIP_DEPRECATED\b"] = (
f'/Deprecated="{CONTEXT.deprecated_message}"/'
)
else:
replacements[r"\bSIP_DEPRECATED\b"] = f"/Deprecated/"

for _pattern, replacement in replacements.items():
line = re.sub(_pattern, replacement, line)

# Combine multiple annotations
while True:
new_line = re.sub(
r'/([\w,]+(="?[\w, \[\]]+"?)?)/\s*/([\w,]+(="?[\w, \[\]]+"?)?]?)/',
r"/\1,\3/",
line,
r'/([\w,]+(="?[^"]+"?)?)/\s*/([\w,]+(="?[^"]+"?)?]?)/', r"/\1,\3/", line
)
if new_line == line:
break
Expand Down
24 changes: 21 additions & 3 deletions scripts/sipify_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@
set -e

CLASS_MAP=0
while getopts "m" opt; do
DEPRECATED_MESSAGE=0
while getopts "md" opt; do
case $opt in
m)
CLASS_MAP=1
;;
d)
DEPRECATED_MESSAGE=1
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
Expand All @@ -47,6 +51,14 @@ else
modules=(core gui analysis server 3d)
fi

pids=()
iPid=0

GENERATE_DEPRECATED_MESSAGE=""
if [[ ${DEPRECATED_MESSAGE} -eq 1 ]]; then
GENERATE_DEPRECATED_MESSAGE="-generate_deprecated_message"
fi

for root_dir in python python/PyQt6; do

if [[ $root_dir == "python/PyQt6" ]]; then
Expand Down Expand Up @@ -83,13 +95,19 @@ It is not aimed to be manually edited
if [[ ${CLASS_MAP} -eq 1 ]]; then
CLASS_MAP_CALL="-c ${module_dir}/class_map.yaml"
fi
./scripts/sipify.py $IS_QT6 -s ${root_dir}/${sipfile}.in -p ${module_dir}/auto_additions/${pyfile} ${CLASS_MAP_CALL} ${header} &
./scripts/sipify.py $IS_QT6 $GENERATE_DEPRECATED_MESSAGE -s ${root_dir}/${sipfile}.in -p ${module_dir}/auto_additions/${pyfile} ${CLASS_MAP_CALL} ${header} &
pids[iPid]=$!
iPid=$((iPid+1))

fi
count=$((count+1))
done < <( ${GP}sed -n -r "s@^%Include auto_generated/(.*\.sip)@${module}/auto_generated/\1@p" python/${module}/${module}_auto.sip )
done
done
wait # wait for sipify processes to finish

for pid in "${pids[@]}"; do
wait $pid || ( echo "Errors while calling sipify!!!" && exit 1 )
done

if [[ ${CLASS_MAP} -eq 1 ]]; then
for root_dir in python python/PyQt6; do
Expand Down
Loading
Loading