In the middle of the desert you can say anything you want
github/git-sizer: Compute various size metrics for a Git repository, flagging those that might cause problems (linked by Repository limitations and recommendations)
TL;DR too many files? too large one? too many tags? Find out!
So Slicer seems to use both and I need to as well, so I’ll have to learn that sooner or later.
open-source, cross-platform library that provides developers with an extensive suite of software tools for image analysis (About | ITK)
there’s a python package docu:
In pycharm, updated black to use these args:
--preview --enable-unstable-feature string_processing $FilePath$
The (future of the) Black code style - Black 24.8.0 documentation has both the preview style and the unstable features one can enable (by passing the flag multilple times).
string_processing
breaks long strings into multiple shorter ones, one on each line.
Useful:
mypy cares about packages, especially __init__.py
files — the uppermost dir with such a file will be the root package. See Mapping files to modules - Running mypy and managing imports - mypy 1.12.0+dev.ecfab6a02415c46eda5717ec6ee9bfac8115c1e9.dirty documentation
This is needed to do per-package configs
[mypy-mycode.package.etc]
disable_error_code = attr-defined, union-attr
Problem: the pycharm extension I have crashes in the last version. :(
Main and best: python - How to run Pylint with PyCharm - Stack Overflow
My changes:
--msg-template="{abspath}:{line:5d},{column:2d}: {C}/{msg} ({symbol})" --output-format=colorized "$FilePath$"
"
, otherwise it failed for me, and {C}
— for the message class see man page (or below) for list of format string options.$FILE_PATH$:\s*$LINE$\,\s*$COLUMN$
I had two options as separate tools:
$FileParentDir$
at the end.--recursive=y
— fails on no __init__.py
otherwiseWorked neatly with a .pylintrc
file in repo root with e.g.
[tool.pylint.main]
[tool.pylint.basic]
# "too-few-public-methods", disable
min-public-methods=0
function-naming-style="camelCase"
argument-naming-style="camelCase"
method-naming-style="camelCase"
variable-naming-style="camelCase"
attr-naming-style="camelCase"
[tool.pylint."messages control"]
disable = [
"fixme", # TODOs
"import-error", # runner has them in its environment
"import-outside-toplevel", # explicit requirement of XXX to import where used
"duplicate-code" # entangling different extensions/modules is not the solution
]
Pylint format string options from man pylint
:
path relative path to the file
abspath
absolute path to the file
line line number
column column number
end_line
line number of the end of the node
end_column
column number of the end of the node
module module name
obj object within the module (if any)
msg text of the message
msg_id the message code (eg. I0011)
symbol symbolic name of the message (eg. locally-disabled)
C one letter indication of the message category
category
fullname of the message category
For example, the former (pre 1.0) default format can be obtained with:
pylint --msg-template='{msg_id}:{line:3d},{column}: {obj}: {msg}'
If I have this post open, I’ll need this one anyway: Messages control - Pylint 4.0.0-dev0 documentation
Is ‘file’ a keyword in python? - Stack Overflow
TL;DR python3 doesn’t care about file
, regardless of what syntax highlighters think about this.
TL;DR:
docstring-convention=google
in flake8 config file, ignores there as well together with the rest.pydocstyle / python-flake8-docstrings is a thing. Forgot I had it installed and spent a lot of time trying to understand pycharm’s output
Usage — pydocstyle 0.0.0.dev0 documentation flake8-docstrings · PyPI
To ignore things, you don’t do:
[pydocstyle]
convention = google
ignore = D401
It’s either ignore or convention. Which quietly happened in the background, and I thought it doesn’t read my config file since D401 was still shown.
Correct would be this:
[pydocstyle]
convention = google
add-ignore = D401
EDIT GodDAMN it, pydocsyle parsing a config file doesn’t mean that flake8(-..docstring) will.
Reading the flake8 plugin docs, I should add THIS and to flake8 config file. Ignores also are set up there using the usual way.
docstring-convention=google
And the pydoctest config file search and add-ignore
is irrelevant. God lost so much time to this
EDIT: this may be all wrong, in the debugger I can just edit the code and it gets automatically used by slicer — logical, since it’s just a CLI script.
It’s the .xml with the interface that’s problematic and it can’t be reloaded using the method below, or at least I couldn’t.
A scriptedcli module imported to Slicer doesn’t show for me the usual “reload” buttons as seen in scripted modules in dev. mode. To develop, I need my changes I need to reload it w/o restarting 3dslicer.
Based on this more complete example1 linked in the script repository2
>>> mpath = "/full/path/to/the/my_module.py"
>>> factoryManager = slicer.app.moduleManager().factoryManager()
>>> factoryManager.registerModule(qt.QFileInfo(mpath))
>>> factoryManager.loadModules(["my_module"])
True
BONUS:
import pydevd_pycharm
pydevd_pycharm.settrace('localhost', port=5678, stdoutToServer=True, stderrToServer=True)
os.getpid()
is my friend/opt/pycharm-professional/debug-eggs/pydevd-pycharm.egg
Loads the module automatically (for some reason doing it manually doesn’t preserve it across restarts?..)
Slicer --additional-module-path /path/to/my/extension/one/lower/than/what/i/would/pick/in/Slicer/GUI
logging.warning("test")
in the python console and it worksDifferent types of modules exist: Module Overview — 3D Slicer documentation
In the first tests there was a lot of latency.
Solution: CLI modules (not extensions) that can run in the background and whose status can be queried, which can be added to new extension from extension editor.
Now I understad this better:
scripted
. It’s the sample thresholding extension
I hope it’s the same as type CLI, but only with python
Is a CLI script w/ an XML that has module metadata + examples
Adding it added it to CMakeLists.xml: add_subdirectory(my_scripted_cli)
python dev tools actually show the CLI used to run a CLI module!
can’t debug it the usual way, I guess I’ll have to add the pydevd-pycharm things to the code
[VTK] /opt/3dslicer/bin/python-real /home/.../cli_model_service.py /tmp/Slicer-sh/IACHCI_vtkMRMLScalarVolumeNodeD.nrrd 1 /tmp/Slicer-sh/IACHCI_vtkMRMLScalarVolumeNodeF.nrrd
Slicer/Docs/developer_guide/parameter_nodes/gui_creation.md at main · Slicer/Slicer seems interesting
CLI modules have an interface specified by the .xml file, and the interface is generated based on it
Bits about the XML
channel
is either input
or output
, and only for pics.index
If I read the volume as volume, it uses the .nrrd
file extension by default — and I want .nii
Module from console with arguments - Support - 3D Slicer Community
Slicer.exe --python-code "selectModule('SampleData'); getModuleGui('SampleData').setCategoryVisible('BuiltIn', False)"
Script repository — 3D Slicer documentation:
# Create a new directory where the scene will be saved into
import time
sceneSaveDirectory = slicer.app.temporaryPath + "/saved-scene-" + time.strftime("%Y%m%d-%H%M%S")
if not os.access(sceneSaveDirectory, os.F_OK):
os.makedirs(sceneSaveDirectory)
outputSegmentation.AddDefaultStorageNode()
outputSegmentation.GetStorageNode().SetFileName(output_segmentation_path)
outputSegmentation.GetStorageNode().ReadData(outputSegmentation)