Excited to share that xptr is back on
CRAN! The xptr package
helps to create, check, modify, use, share, external pointer
objects.
External pointers are used quite extensively throughout R to manage external resources
such as datanbase connection objects and alike, and can be very useful
to pass pointers to just about any C / C++ data structure around. While
described in Writing
R Extensions (notably Section
5.13), they can be a little bare-bones and so this package can be
useful. It had been created by Randy
Lai and maintained by him during 2017 to 2020, but then fell off
CRAN. In work with nanoarrow and
its clean and minimal Arrow interface xptr came in
handy so I adopted it.
Several extensions and updates have been added: (compiled) function
registration, continuous integration, tests, refreshed and extended
documentation as well as a print format extension useful for PyCapsule
objects when passing via reticulate. The
package documentation
site was switched to altdoc driving the
most excellent Material for
MkDocs framework (providing my first test case of altdoc replacing my
older local scripts; I should post some more about that ).
The first NEWS entry follow.
For more, see the package page, the git repo or the documentation site.Changes in version 1.2.0 (2025-10-03)
- New maintainer
- Compiled functions are now registered,
.Call()adjusted- README.md and DESCRIPTION edited and update
- Simple unit tests and continunous integration have been added
- The package documentation site has been recreated using altdoc
- All manual pages for functions now contain
\valuesections
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can sponsor me at GitHub.
incus launch images:debian/trixie <instance-name> --vm
incus shell <instance-name>
apt install git distrobuilder
git clone --branch support-debian-buster https://github.com/charles2910/lxc-ci.git
# and cd into it
cd lxc-ci
mkdir -p /tmp/images/buster/container
# and perform the build
distrobuilder build-incus images/debian.yaml /tmp/images/buster/container/ \
-o image.architecture=amd64 \
-o image.release=buster \
-o image.variant=default \
-o source.url="http://archive.debian.org/debian"
images/ subdir.
If all worked correctly, you should have two files in your pre-defined target
directory. In our case, /tmp/images/buster/container/ contains:
incus.tar.xz rootfs.squashfs
incus file pull <instance-name>/tmp/images/buster/container/incus.tar.xz .
incus file pull <instance-name>/tmp/images/buster/container/rootfs.squashfs .
# and import it as debian/10
incus image import incus.tar.xz rootfs.squashfs --alias debian/10
incus launch local:debian/10 <debian-buster-instance>
incus shell <debian-buster-instance>
apt install --assume-yes wget
wget https://deb.freexian.com/extended-lts/archive-key.gpg -O /etc/apt/trusted.gpg.d/freexian-archive-extended-lts.gpg
cat <<EOF >/etc/apt/sources.list.d/extended-lts.list
deb http://deb.freexian.com/extended-lts buster-lts main contrib non-free
EOF
apt update
apt --assume-yes upgrade
About 90% of my Debian contributions this month were
sponsored by Freexian.
You can also support my work directly via
Liberapay or GitHub
Sponsors.
Some months I feel like I m pedalling furiously just to keep everything in a
roughly working state. This was one of those months.
Python team
I upgraded these packages to new upstream versions:
pybuild-plugin-pyproject:
pkg_resources is
deprecated. In most cases
replacing it is a relatively simple matter of porting to
importlib.resources,
but packages that used its old namespace package support need more
complicated work to port them to implicit namespace
packages. We had quite a few bugs about
this on zope.* packages, but fortunately upstream did the hard part of
this recently. I went
round and cleaned up most of the remaining loose ends, with some help from
Alexandre Detiste. Some of these aren t completely done yet as they re
awaiting new upstream releases:
nocheck profile.
I fixed several other build/test failures:
I fixed some other bugs:
A new version 0.3.5 of the RPushbullet
package arrived on CRAN. It
marks the first release in 4 1/2 years for this mature and
feature-stable package. RPushbullet
interfaces the neat Pushbullet
service for inter-device messaging, communication, and more. It lets you
easily send (programmatic) alerts like the one to the left to your
browser, phone, tablet, or all at once.
This releases reflects mostly internal maintenance and updates to the
documentation
site, to continuous integration, to package metadata, and one code
robustitication. See below for more details.
Courtesy of my CRANberries, there is a diffstat report relative to previous release. More detailed information is on the repo where comments and suggestions are welcome.Changes in version 0.3.5 (2025-10-08)
- URL and BugReports fields have been added to DESCRIPTION
- The
pbPostfunction deals more robustly with the case of multiple target emails- The continuous integration and the README badge have been updated
- The DESCRIPTION file now use Authors@R
- The (encrypted) unit test configuration has been adjusted to reflect the current set of active devices
- The mkdocs-material documentation site is now generated via altdoc
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can sponsor me at GitHub.
md_in_html extension and use the
markdown attribute for it to kick in on the <details> html tag.
Add the extension to your mkdocs.yaml:
markdown_extensions:
- md_in_html
Hide the table in your markdown document in a collapsible element
like this:
<details markdown>
<summary>Long Table</summary>
Foo Bar
- -
Fizz Buzz
</details>
It's also required to have an empty line between the html tag and starting
the markdown part. Rendered for me that way in VSCode, GitHub and Backstage.
Welcome to post 53 in the R4 series.
Continuing with posts #51
from Tuesday and #52
from Wednesday and their stated intent of posting some more here
is another quick one. Earlier today I helped another package developer
who came to the r-package-devel list asking for help with a build error
on the Fedora machine at CRAN running recent / development
clang. In such situations, the best first step is often to
replicate the issue. As I pointed out on the list, the LLVM team behind
clang maintains an apt repo
at apt.llvm.org/ making it a good resource to add to Debian-based
container such as Rocker r-base or the offical r-base (the two
are in fact interchangeable, and I take care of both).
A small pothole, however, is that the documentation at the top of apt.llvm.org site is a bit stale and
behind two aspects that changed on current Debian systems
(i.e. unstable/testing as used for r-base). First,
apt now prefers files ending in .sources (in a
nicer format) and second, it now really requires a key (which is good
practice). As it took me a few minutes to regather how to meet both
requirements, I reckoned I might as well script this.
Et voil the following script does that:
~/.R/Makevars to use that
compilerclang-22 (and clang++-22)
(still using the g++ C++ library)#!/bin/sh
## Update does not hurt but is not strictly needed
#apt update --quiet --quiet
#apt upgrade --yes
## wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
## or as we are root in container
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key > /etc/apt/trusted.gpg.d/apt.llvm.org.asc
cat <<EOF >/etc/apt/sources.list.d/llvm-dev.sources
Types: deb
URIs: http://apt.llvm.org/unstable/
# for clang-21
# Suites: llvm-toolchain-21
# for current clang
Suites: llvm-toolchain
Components: main
Signed-By: /etc/apt/trusted.gpg.d/apt.llvm.org.asc
EOF
test -d ~/.R mkdir ~/.R
cat <<EOF >~/.R/Makevars
CLANGVER=-22
# CLANGLIB=-stdlib=libc++
CXX=clang++\$(CLANGVER) \$(CLANGLIB)
CXX11=clang++\$(CLANGVER) \$(CLANGLIB)
CXX14=clang++\$(CLANGVER) \$(CLANGLIB)
CXX17=clang++\$(CLANGVER) \$(CLANGLIB)
CXX20=clang++\$(CLANGVER) \$(CLANGLIB)
CC=clang\$(CLANGVER)
SHLIB_CXXLD=clang++\$(CLANGVER) \$(CLANGLIB)
EOF
apt update
apt install --yes clang-22clang-22 and clang++-22. This may help
R package developers. The script is also generic enough for other
development communities who can ignore (or comment-out / delete) the bit
about ~/.R/Makevars and deploy the compiler differently.
Updating the softlink as apt-preferences does is one way
and done in many GitHub Actions recipes. As we only need
wget here a basic Debian container should work, possibly
with the addition of wget. For R users r-base
hits a decent sweet spot.
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub.
There's a new Nine Inch Nails album! That
doesn't happen very often.
There's a new Trent Reznor & Atticus Ross soundtrack! That happens
all the time!
For the first time, they're the same thing.
The new one, Tron: Ares, is very deliberately presented as a Nine Inch Nails
album, and not a TR&AR soundtrack. But is it neither fish nor fowl? 24 tracks,
four with lyrics. Singing is not unheard of on TR&AR soundtracks,
but it's rare (A Minute to Breathe from the excellent Before the Flood
is another). Instrumentals are not rare on NIN albums, either, but this ratio
is very unusual, and has disappointed some fans who were hoping for a more
traditional NIN album.
What does it mean to label something a NIN album anyway? For me, the lines are
now further blurred. One thing for sure is it means a lot of media attention,
and this release, as well as the film it's promoting, are all over the media
at the moment. Posters, trailers, promotional tie-in items, Disney logos
everywhere. The album is hitched to the Disney marketing and promotion machine.
It's a bit weird seeing the NIN logo all over the place advertising the movie.
On to the music. I love TR&AR soundtracks, and some of my favourite NIN tracks
are instrumentals. Despite that, three highlights for me are songs: As Alive
As You Need Me To Be, I Know You Can Feel It and closer Shadow Over Me.
The other stand-out is Building Better Worlds, a short instrumental and
clear nod to Wendy Carlos.
My main complaint here applies to some of the more recent soundtracks as well:
the tracks are too short. They're scored to scenes in the movie, which makes a
lot of sense in that presentation, but less so for independent listening. It's
not a problem that their earlier, lauded soundtracks suffered (The Social Network,
Before the Flood, Bird Box Extended). Perhaps a future remix album will address that.
Another short status update of what happened on my side last
month. Nothing stands out too much, I enjoyed doing the OSK changes
the most as that helped to improve the typing experience further. Also
doing a small bit of kernel work again was fun (still need to figure out
the 6mq's touch controller repsonsiveness though).
See below for details on the above and more:
phosh
gbp import-orig --uscan useful again when passing in a version (MR)
A tiniest of tiny violins micro maintenance release 0.0.4 of our tinythemes arrived
on CRAN today. tinythemes
provides the theme_ipsum_rc() function from hrbrthemes by Bob Rudis in a zero (added) dependency way. A
simple example is (also available as a demo inside the package)
contrasts the default style (on the left) with the one added by this
package (on the right):
This version adjusts to the fact that hrbrthemes is no
longer on CRAN so the help page
cannot link to its documentation. No other changes were made.
The set of changes since the last release follows.
Courtesy of my CRANberries, there is a diffstat report relative to previous release. More detailed information is on the repo where comments and suggestions are welcome.Changes in tinythemes version 0.0.4 (2025-10-02)
- No longer
\linkto now-archived hrbrthemes
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can sponsor me at GitHub.
Welcome to post 52 in the R4 series.
Following up on the post #51
yesterday and its stated intent of posting some more here The r-ci setup (which was
introduced in post
#32 and updated in post
#45) offers portable continuous integration which can take
advantage of different backends: Github Actions, Azure Pipelines,
GitLab, BitBuckets, and possibly as it only requires a basic Ubuntu
shell after which it customizes itself and runs via shell script.
Portably. Now, most of us, I suspect still use it with GitHub Actions
but it is reassuring to know that one can take it elsewhere should the
need or desire arise.
One thing many repos did, and which stopped working reliably is
coverage analysis. This is made easy by the covr package, and
made fast, easy, reliable (as we quip) thanks to r2u. But transmission to
codecov stopped working a while back so
I had mostly commented it out in my repos, rendering the reports more
and more stale. Which is not ideal.
A few weeks ago I gave this another look, and it turns that that codecov now requires an API token
to upload. Which one can generate in the user -> settings menu on
their website under the access tab. Which in turn then needs to be
stored in each repo wanting to upload. For Github, this is
under settings -> secrets and variables -> actions as a
repository secret . I suggest using CODECOV_TOKEN for its
name.
After that the three-line block in the yaml file can reference it as
a secret as in the following snippet, now five lines, taken from one of
my ci.yaml files:
- name: Coverage
if: $ matrix.os == 'ubuntu-latest'
run: ./run.sh coverage
env:
CODECOV_TOKEN: $ secrets.CODECOV_TOKEN secrets. and assigns it to the environment variable
CODECOV_TOKEN. After this reports flow as one can see on
repositories where I re-enabled this as for example here for
RcppArmadillo.
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub.
Last month I attended and spoke at
Kangrejos, for which I will post a separate
report later. Besides that, here s the usual categorised list of work:
libscfg is a C
implementation of the scfg configuration
file format and it is a dependency of recent version of
kanshi. kanshi is a tool
similar to autorandr which allows you define output profiles and kanshi
switches to the correct output profile on hotplug events. Once libscfg is in
unstable I can finally update kanshi to the latest version.
A lot of time this month in finalizing a redesign of the output rendering of
carl. carl is a small rust program I wrote
that provides a calendar view similar to cal, but it comes with colors and
ical file integration. That means that you can not only display a simple
calendar, but also colorize/highlight dates based on various attributes or
based on events on that day. In the initial versions of carl the output
rendering was simply hardcoded into the app.
carl to use templates. I chose the
minijinja Rust library which is
based on the syntax and behavior of the Jinja2 template engine for Python .
There are others out there, like tera, but
minijinja seems to be more active in development currently. I worked on this
implementation on and off for the last year and finally had the time to finish
it up and write some additional tests for the outputs. It is easier to maintain
templates than Rust code that uses write!() to format the output. I also
implemented a configuration option for users to override the templates.
Additional to the output refactoring I also fixed couple of bugs and finally
released v0.4.0 of carl.
In my dayjob I released version 0.53 of apis-core-rdf which contains the place
lookup field which I implemented in August. A couple of weeks later we released
version 0.54 which comes with a middleware to show pass on messages from the
Django messages
framework via
response header to HTMX to trigger message popups. This implementation is based
on the blog post Using the Django messages framework with
HTMX. Version
0.55 was the last release in September. It contained preparations for
refactoring the import logic as well as a couple of UX improvements.
The last (software) piece of sorting out a local voice assistant is tying the openWakeWord piece to a local microphone + speaker, and thus back to Home Assistant. For that we use wyoming-satellite.
I ve packaged that up - https://salsa.debian.org/noodles/wyoming-satellite - and then to run I do something like:
$ wyoming-satellite --name 'Living Room Satellite' \
--uri 'tcp://[::]:10700' \
--mic-command 'arecord -r 16000 -c 1 -f S16_LE -t raw -D plughw:CARD=CameraB409241,DEV=0' \
--snd-command 'aplay -D plughw:CARD=UACDemoV10,DEV=0 -r 22050 -c 1 -f S16_LE -t raw' \
--wake-uri tcp://[::1]:10400/ \
--debug
aplay/arecord to talk to the local microphone and speaker, and gives us some debug output so we can see what s going on.
And it turns out we need the debug. This setup is a bit too flaky for it to have ended up in regular use in our household. I ve had some problems with reliable audio setup; you ll note the Python is calling out to other tooling to grab audio, which feels a bit clunky to me and I don t think is the actual problem, but the main audio for this host is hooked up to the TV (it s a media box), so the setup for the voice assistant needs to be entirely separate. That means not plugging into Pipewire or similar, and instead giving direct access to wyoming-satellite. And sometimes having to deal with how to make the mixer happy + non-muted manually.
I ve also had some issues with the USB microphone + speaker; I suspect a powered USB hub would help, and that s on my list to try out.
When it does work I have sometimes found it necessary to speak more slowly, or enunciate my words more clearly. That s probably something I could improve by switching from the base.en to small.en whisper.cpp model, but I m waiting until I sort out the audio hardware issue before poking more.
Finally, the wake word detection is a little bit sensitive sometimes, as I mentioned in the previous post. To be honest I think it s possible to deal with that, if I got the rest of the pieces working smoothly.
This has ended up sounding like a more negative post than I meant it to. Part of the issue in a resolution is finding enough free time to poke things (especially as it involves taking over the living room and saying Hey Jarvis a lot), part of it is no doubt my desire to actually hook up the pieces myself and understand what s going on. Stay tuned and see if I ever manage to resolve it all!
Welcome to post 51 in the R4 series.
A while back I realized I should really just post a little more as
not all post have to be as deep and introspective as for example the
recent-ish two
cultures post #49.
So this post is a neat little trick I (somewhat belatedly) realized
somewhat recently. The context is the ongoing transition from
(Rcpp)Armadillo 14.6.3 and earlier to (Rcpp)Armadillo 15.0.2 or later.
(I need to write a bit more about that, but that may require a bit more
time.) (And there are a total of seven (!!) issue tickets managing the
transition with issue
#475 being the main parent issue, please see there for more
details.)
In brief, the newer and current Armadillo no longer allows C++11
(which also means it no longer allowes suppression of deprecation
warnings ). It so happens that around a decade ago packages were
actively encouraged to move towards C++11 so many either set an
explicit SystemRequirements: for it, or set CXX_STD=CXX11
in src/Makevars .win . CRAN has for some time now issued
NOTEs asking for this to be removed, and more recently enforced this
with actual deadlines. In RcppArmadillo I opted to accomodate old(er)
packages (using this by-now anti-pattern) and flip to Armadillo 14.6.3
during a transition period. That is what the package does now: It gives
you either Armadillo 14.6.3 in case C++11 was detected (or this legacy
version was actively selected via a compile-time #define),
or it uses Armadillo 15.0.2 or later.
So this means we can have either one of two versions, and may want to
know which one we have. Armadillo carries its own version macros, as
many libraries or projects do (R of course included). Many many years
ago (git blame points to sixteen and twelve for a revision)
we added the following helper function to the package (full source here,
we show it here without the full roxygen2 comment header)
// [[Rcpp::export]]
Rcpp::IntegerVector armadillo_version(bool single)
// These are declared as constexpr in Armadillo which actually does not define them
// They are also defined as macros in arma_version.hpp so we just use that
const unsigned int major = ARMA_VERSION_MAJOR;
const unsigned int minor = ARMA_VERSION_MINOR;
const unsigned int patch = ARMA_VERSION_PATCH;
if (single)
return Rcpp::wrap(10000 * major + 100 * minor + patch) ;
else
return Rcpp::IntegerVector::create(Rcpp::Named("major") = major,
Rcpp::Named("minor") = minor,
Rcpp::Named("patch") = patch);
> library(RcppArmadillo)
> armadillo_version(FALSE)
major minor patch
15 0 2
> armadillo_version(TRUE)
[1] 150002
>package_version. (Full version of one such variant here)
// [[Rcpp::export]]
Rcpp::List armadilloVersion()
// create a vector of major, minor, patch
auto ver = Rcpp::IntegerVector::create(ARMA_VERSION_MAJOR, ARMA_VERSION_MINOR, ARMA_VERSION_PATCH);
// and place it in a list (as e.g. packageVersion() in R returns)
auto lst = Rcpp::List::create(ver);
// and class it as 'package_version' accessing print() etc methods
lst.attr("class") = Rcpp::CharacterVector::create("package_version", "numeric_version");
return lst;
package_version inheriting from
numeric_version can directly compare against a (human- but
not normally machine-readable) string like 15.0.0 because the simple
S3 class defines appropriate operators, as well as print()
/ format() methods as the first expression shows. It is
these little things that make working with R so smooth, and we can
easily (three statements !!) do so from Rcpp-based packages too.
The underlying object really is merely a list containing a
vector:
but the S3 glue around it makes it behave nicely.
So next time you are working with an object you plan to return to R,
consider classing it to take advantage of existing infrastructure (if it
exists, of course). It s easy enough to do, and may smoothen the
experience at the R side.
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub.
During 2025-03-21-another-home-outage, I reflected upon what's a properly ran service and blurted out what turned out to be something important I want to outline more. So here it is, again, on its own for my own future reference.Typically, I tend to think of a properly functioning service as having four things:
:wq for today.
Next.