Re: [Rd] After package update, old S4 method is dispatched

2023-10-03 Thread Jan Netík
Simon,

Many thanks for your advice! The issue was that another package was
inheriting from the "mirt" class in question. Apparently, some methods are
cached at build time (is this documented anywhere?). After reinstalling the
package that extends the "mirt" class, the proper method is now being
dispatched. No other packages needed to be reinstalled.

Best,
Jan

po 2. 10. 2023 v 20:56 odesílatel Simon Urbanek 
napsal:

> Jan,
>
> have you re-installed all packages? If you change (update) any package
> that uses S4 it may be necessary to re-install all its reverse-dependencies
> as well since they may include cached values in their namespaces, so the
> easiest is to make sure you re-install all packages.
>
> Cheers,
> Simon
>
>
> > On Oct 3, 2023, at 4:18 AM, Jan Netík  wrote:
> >
> > Hello R-devel,
> >
> > I hope that you are all doing well and that this is the right place to
> > discuss my somewhat mysterious issue with S4.
> >
> > On our Ubuntu server, we have "mirt" package installed which defines S4
> > method for "coef" standard generic. We updated the package with the usual
> > "install.packages", restarted, and observer error calling coef on mirt
> > object that should not be possible: "Error in which: argument "nfact" is
> > missing, with no default" (which has no such argument).
> >
> > After days of investigation, I found that from mirt 1.37 to current 1.40,
> > the method changed as well as some internal functions used by the method.
> > The aforementioned error stems from the fact that these internal ordinary
> > functions were changed properly as we updated the package, but the S4
> > method dispatched stuck with the 1.37 version. I am by no means an expert
> > on S4 matter, but I know that these are cached to some extent. I thought
> > the cache is session-bound and have no idea how the issue can possibly
> > persist even after a complete reboot of the machine. I can detach and
> > library() mirt in one R session which solves the issue temporarily, but
> > emerges right back in any new R session.
> >
> > Sadly, I cannot provide any reproducible example as I am completely
> unaware
> > of the cause and even I cannot reproduce this issue outside of the
> server.
> >
> > Any insights on how this issue could have started would be highly
> > appreciated.
> >
> > Best regards,
> > Jan Netík
> >
> >   [[alternative HTML version deleted]]
> >
> > __
> > R-devel@r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
> >
>
>

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Problems caused by dev.off() behaviour

2023-10-03 Thread Duncan Murdoch

On 02/10/2023 10:17 p.m., Trevor Davis wrote:

 > Thanks!  However, isn't length(dev.list()) == 0 when there are no
devices?  That's what I'm seeing on MacOS.

Ifthere is only one graphics device then R should automatically set it 
as the active graphics device so it isn't really necessary to manually 
set it.  Although there wouldn't be any harm in manually setting it you 
only really need to worry about setting the previous graphics device 
when there are two or more devices open.


Right, I see.  With some more fiddling, I've decided that I don't like 
the error you get if you try to close device 1, so here's the current 
version:


safe.dev.off  <- function(which = dev.cur(), prev = dev.prev()) {
  if (which != 1) {
force(prev)
grDevices::dev.off(which)
  }
  if (length(dev.list()))
dev.set(prev)
  else
c("null device" = 1)
}

This does the dev.set even if there's only one device so it can return 
the resulting device number.


Duncan Murdoch



Trevor

On Mon, Oct 2, 2023 at 5:25 PM Duncan Murdoch > wrote:


Thanks!  However, isn't length(dev.list()) == 0 when there are no
devices?  That's what I'm seeing on MacOS.

Duncan Murdoch

On 02/10/2023 4:21 p.m., Trevor Davis wrote:
 >  > Use it just like dev.off(), but it *will* restore the previous
device.
 >
 > I'm observing that if there were no previously open graphics devices
 > then your `safe.dev.off()` opens up a new graphics device which
may be
 > an undesired side effect (because "surprisingly" `dev.set()` on
the null
 > graphics device opens up a new graphics device).  To avoid that you
 > could check if `dev.list()` is greater than length 1L:
 >
 >     safe.dev.off  <- function(which = dev.cur(), prev = dev.prev()) {
 >       force(prev)
 >       dev.off(which)
 >       if (length(dev.list()) > 1L) {
 >         dev.set(prev)
 >       }
 >     }
 >
 > Trevor
 >
 > On Mon, Oct 2, 2023 at 11:54 AM Duncan Murdoch
mailto:murdoch.dun...@gmail.com>
 > >> wrote:
 >
 >     I found some weird behaviour and reported it as
 > https://bugs.r-project.org/show_bug.cgi?id=18604

 >     > and
 > https://github.com/yihui/knitr/issues/2297

 >     >, but it turns out it
 >     was user
 >     error.
 >
 >     The dev.off() function was behaving as documented, but it
behaves in an
 >     unexpected (by me) way, and that caused the "bugs".
 >
 >     The issue is that
 >
 >          dev.off()
 >
 >     doesn't always result in the previous graphics device being made
 >     current.  If there are two or more other open graphics
devices, it
 >     won't
 >     choose the previous one, it will choose the next one.
 >
 >     I'm letting people know because this might affect other
people too.  If
 >     you use dev.off(), don't assume it restores the previous device!
 >
 >     Here's my little workaround alternative:
 >
 >         safe.dev.off  <- function(which = dev.cur(), prev =
dev.prev()) {
 >           force(prev)
 >           dev.off(which)
 >           dev.set(prev)
 >         }
 >
 >     Use it just like dev.off(), but it *will* restore the
previous device.
 >
 >     Duncan Murdoch
 >
 >     __
 > R-devel@r-project.org 
>
mailing list
 > https://stat.ethz.ch/mailman/listinfo/r-devel

 >     >
 >



__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] [External] On PRINTNAME() encoding, EncodeChar(), and being painted into a corner

2023-10-03 Thread Ivan Krylov
Dear Luke Tierney,

Thank you for the reply and apologies for not getting back to you
earlier.

On Fri, 22 Sep 2023 16:14:58 -0500 (CDT)
luke-tier...@uiowa.edu wrote:

> I think it would be best to modify errorcall so errorcall_cpy is not
> necessary. As things are now it is just too easy to forget that
> sometimes errorcall_cpy should be used (and this has lead to some bugs
> recently).

At the end of this e-mail is a large patch that makes errorcall() and
warningcall() safer by processing the format arguments before calling
any R APIs. It's fairly invasive because it rewires all error() /
warning() / errorcall() / warningcall() processing into two common
subroutines that call R_vsnprintf() as soon as possible and keep a
single message buffer afterwards. It passes make check-devel. I am open
to other, less invasive ways to implement this change.

Additionally, I fixed a problem detected by a static analyser: given
unsigned msg_len, max(msg_len - strlen(head), 0) can only be 0 if
msg_len == strlen(head). That's because both msg_len and size_t end up
being promoted to unsigned in order to compute the subtraction. I
couldn't come up with a sufficiently laconic alternative, so I left the
ternary operator in for now.

>> The only solution to the latter problem is an EncodeChar() variant
>> that allocates its memory dynamically. Would R_alloc() be
>> acceptable in this context? With errors, the allocation stack would
>> be quickly reset (except when withCallingHandlers() is in effect?),
>> but with warnings, the code would have to restore it manually every
>> time.  
> 
> Or allow/require a buffer to be provided. So replacing the calls like
> 
> CHAR(PRINTNAME(sym))
> 
> with
> 
> EncodeSymbol(sym, buf, buf_size)

I can also implement this. Does this mean replacing every occasion of
EncodeChar(PRINTNAME(sym)) with EncodeSymbol(sym, , sizeof
)?

Index: src/main/envir.c
===
--- src/main/envir.c(revision 85251)
+++ src/main/envir.c(working copy)
@@ -1582,7 +1582,7 @@
}
rho = ENCLOS(rho);
 }
-errorcall_cpy(call,
+errorcall(call,
   _("could not find function \"%s\""),
   EncodeChar(PRINTNAME(symbol)));
 /* NOT REACHED */
@@ -3924,7 +3924,7 @@
 SEXP nsname = PROTECT(callR1(R_getNamespaceNameSymbol, ns));
 if (TYPEOF(nsname) != STRSXP || LENGTH(nsname) != 1)
errorcall(call, "bad value returned by `getNamespaceName'");
-errorcall_cpy(call,
+errorcall(call,
  _("'%s' is not an exported object from 'namespace:%s'"),
  EncodeChar(PRINTNAME(name)),
  CHAR(STRING_ELT(nsname, 0)));
Index: src/main/errors.c
===
--- src/main/errors.c   (revision 85251)
+++ src/main/errors.c   (working copy)
@@ -58,7 +58,7 @@
 /*
 Different values of inError are used to indicate different places
 in the error handling:
-inError = 1: In internal error handling, e.g. `verrorcall_dflt`, others.
+inError = 1: In internal error handling, e.g. `errorcall_dflt`, others.
 inError = 2: Writing traceback
 inError = 3: In user error handler (i.e. options(error=handler))
 */
@@ -387,32 +387,45 @@
return c ? c->call : R_NilValue;
 }
 
-void warning(const char *format, ...)
+/* declarations for internal condition handling */
+
+static void signalError(SEXP call, const char *msg);
+static void signalWarning(SEXP call, const char *msg);
+NORET static void invokeRestart(SEXP, SEXP);
+
+static void impl_vwarning(SEXP call, Rboolean immediate, const char *format, 
va_list ap)
 {
 char buf[BUFSIZE], *p;
 
-va_list(ap);
-va_start(ap, format);
 size_t psize;
 int pval;
 
 psize = min(BUFSIZE, R_WarnLength+1);
 pval = Rvsnprintf_mbcs(buf, psize, format, ap);
-va_end(ap);
 p = buf + strlen(buf) - 1;
 if(strlen(buf) > 0 && *p == '\n') *p = '\0';
 RprintTrunc(buf, pval >= psize);
-SEXP call = PROTECT(getCurrentCall());
-warningcall(call, "%s", buf);
-UNPROTECT(1);
+
+// must not call into R before stringifying the format arguments
+int nprotect = 0;
+if (!call) {
+   call = PROTECT(getCurrentCall());
+   ++nprotect;
+}
+if (immediate) immediateWarning = 1;
+signalWarning(call, buf);
+if (immediate) immediateWarning = 0;
+UNPROTECT(nprotect);
 }
 
-/* declarations for internal condition handling */
+void warning(const char *format, ...)
+{
+va_list(ap);
+va_start(ap, format);
+impl_vwarning(NULL, FALSE, format, ap);
+va_end(ap);
+}
 
-static void vsignalError(SEXP call, const char *format, va_list ap);
-static void vsignalWarning(SEXP call, const char *format, va_list ap);
-NORET static void invokeRestart(SEXP, SEXP);
-
 static void reset_inWarning(void *data)
 {
 inWarning = 0;
@@ -437,12 +450,11 @@
 return nc;
 }
 
-static void vwarningcall_dflt(SEXP call, const char 

[Rd] as(, "dgTMatrix")' is deprecated.

2023-10-03 Thread Koenker, Roger W
I’ve been getting this warning for a while now (about five years if memory 
serves) and I’m finally tired of it, but also too tired to track it down in 
Matrix.  As far as I can grep  I have no reference to either deprecated object, 
only the apparently innocuous  Matrix::Matrix(A, sparse = TRUE).  Can someone 
advise, Martin perhaps?  I thought it might come from Rmosek, but mosek folks 
don’t think so.
https://groups.google.com/g/mosek/c/yEwXmMfHBbg/m/l_mkeM4vAAAJ

All the best to all the best of the R community,
R
__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] as(, "dgTMatrix")' is deprecated.

2023-10-03 Thread Duncan Murdoch

On 03/10/2023 12:50 p.m., Koenker, Roger W wrote:

I’ve been getting this warning for a while now (about five years if memory 
serves) and I’m finally tired of it, but also too tired to track it down in 
Matrix.  As far as I can grep  I have no reference to either deprecated object, 
only the apparently innocuous  Matrix::Matrix(A, sparse = TRUE).  Can someone 
advise, Martin perhaps?  I thought it might come from Rmosek, but mosek folks 
don’t think so.
https://groups.google.com/g/mosek/c/yEwXmMfHBbg/m/l_mkeM4vAAAJ


A quick scan of that discussion didn't turn up anything relevant, e.g. a 
script to produce the warning.  Could you be more specific, or just post 
the script here?


In general, a good way to locate the source of a warning is to set 
options(warn=2) to turn it into an error, and then trigger it.  The 
traceback from the error will include a bunch of junk from the code that 
catches the warning, but it will also include the context where it was 
triggered.


Duncan Murdoch

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] as(, "dgTMatrix")' is deprecated.

2023-10-03 Thread Martin Maechler
> Duncan Murdoch 
> on Tue, 3 Oct 2023 12:59:10 -0400 writes:

> On 03/10/2023 12:50 p.m., Koenker, Roger W wrote:
>> I’ve been getting this warning for a while now (about
>> five years if memory serves) and I’m finally tired of it,
>> but also too tired to track it down in Matrix.  As far as
>> I can grep I have no reference to either deprecated
>> object, only the apparently innocuous Matrix::Matrix(A,
>> sparse = TRUE).  Can someone advise, Martin perhaps?  I
>> thought it might come from Rmosek, but mosek folks don’t
>> think so.
>> https://groups.google.com/g/mosek/c/yEwXmMfHBbg/m/l_mkeM4vAAAJ

> A quick scan of that discussion didn't turn up anything
> relevant, e.g. a script to produce the warning.  Could you
> be more specific, or just post the script here?

> In general, a good way to locate the source of a warning
> is to set options(warn=2) to turn it into an error, and
> then trigger it.  The traceback from the error will
> include a bunch of junk from the code that catches the
> warning, but it will also include the context where it was
> triggered.

> Duncan Murdoch

Indeed.

But Roger is right that it in the end, (almost surely) it is
from our {Matrix} package.

Indeed for several years now, we have tried to make the setup
leaner (and hence faster) by not explicitly define coercion
from  to   because  the size of
 is here about 200, and we don't want to have to provide
200^2 = 40'000  coercion methods.

Rather, Matrix package users should use to high level abstract Matrix
classes such as "sparseMatrix" or "CsparseMatrix" or
"TsparseMatrix" or "dMatrix", "symmetricMatrix".

In the case of  as(, "dgTMatrix") , if you
replace "dgTMatrix" by "TsparseMatrix"
the result will be the same but also work in the future when the
deprecation may have been turned into a defunctation ...

Martin

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] as(, "dgTMatrix")' is deprecated.

2023-10-03 Thread Koenker, Roger W
There is a call to mosek and I assumed that this wasn’t going to be helpful for 
most R-devel recipients.  I tried Duncan’s very reasonable suggestion about 
options() but it didn’t produce the desired error, so perhaps this isn’t really 
a warning  but something else???

For those who might have rmosek installed,  I’m doing:

library(REBayes)
demo(GLmix1)

Thanks,
Roger


> On Oct 3, 2023, at 6:17 PM, Martin Maechler  
> wrote:
> 
>> Duncan Murdoch 
>>on Tue, 3 Oct 2023 12:59:10 -0400 writes:
> 
>> On 03/10/2023 12:50 p.m., Koenker, Roger W wrote:
>>> I’ve been getting this warning for a while now (about
>>> five years if memory serves) and I’m finally tired of it,
>>> but also too tired to track it down in Matrix.  As far as
>>> I can grep I have no reference to either deprecated
>>> object, only the apparently innocuous Matrix::Matrix(A,
>>> sparse = TRUE).  Can someone advise, Martin perhaps?  I
>>> thought it might come from Rmosek, but mosek folks don’t
>>> think so.
>>> https://urldefense.com/v3/__https://groups.google.com/g/mosek/c/yEwXmMfHBbg/m/l_mkeM4vAAAJ__;!!DZ3fjg!71re8ipw9fFStkMab0wGuPNSzSaAhPI5vwxd1BCQ7a55mYiRpAq2prn9-wREqKL_G2uBYboXISQfxZYCZ9AFxCnwxdzqTw$
>>>  
> 
>> A quick scan of that discussion didn't turn up anything
>> relevant, e.g. a script to produce the warning.  Could you
>> be more specific, or just post the script here?
> 
>> In general, a good way to locate the source of a warning
>> is to set options(warn=2) to turn it into an error, and
>> then trigger it.  The traceback from the error will
>> include a bunch of junk from the code that catches the
>> warning, but it will also include the context where it was
>> triggered.
> 
>> Duncan Murdoch
> 
> Indeed.
> 
> But Roger is right that it in the end, (almost surely) it is
> from our {Matrix} package.
> 
> Indeed for several years now, we have tried to make the setup
> leaner (and hence faster) by not explicitly define coercion
> from  to   because  the size of
>  is here about 200, and we don't want to have to provide
> 200^2 = 40'000  coercion methods.
> 
> Rather, Matrix package users should use to high level abstract Matrix
> classes such as "sparseMatrix" or "CsparseMatrix" or
> "TsparseMatrix" or "dMatrix", "symmetricMatrix".
> 
> In the case of  as(, "dgTMatrix") , if you
> replace "dgTMatrix" by "TsparseMatrix"
> the result will be the same but also work in the future when the
> deprecation may have been turned into a defunctation ...
> 
> Martin


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] as(, "dgTMatrix")' is deprecated.

2023-10-03 Thread Ivan Krylov
On Tue, 3 Oct 2023 16:50:55 +
"Koenker, Roger W"  wrote:

>  I thought it might come from Rmosek, but mosek folks don’t think so.

I downloaded the Rmosek source package using

download.packages(
 'Rmosek', '.',
 repos='https://download.mosek.com/R/10.1'
)

...and there are the deprecated calls:


Rmosek/R$ grep -C2 -r as\(.*dgT
toCSCMatrix.R-  }
toCSCMatrix.R-  else if (is(obj,"dgCMatrix")) {
toCSCMatrix.R:obj <- as(obj,"dgTMatrix")
toCSCMatrix.R-  }
toCSCMatrix.R-  else if (is(obj,"list") && 
setequal(names(obj),c("i","j","v","ncol","nrow"))) {
--
toCSCMatrix.R- x=obj[['v']],
toCSCMatrix.R- dims=c(obj[['nrow']], obj[['ncol']]) )
toCSCMatrix.R:obj <- as(tmp, "dgTMatrix")
toCSCMatrix.R-  }
toCSCMatrix.R-  else if (canCoerce(obj,"dgTMatrix")) {
toCSCMatrix.R-# Assume coercion is meaningful, and that
toCSCMatrix.R-# users are aware of computational overhead.
toCSCMatrix.R:obj <- as(obj,"dgTMatrix")
toCSCMatrix.R-  }
toCSCMatrix.R-  else {


-- 
Best regards,
Ivan

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Problems caused by dev.off() behaviour

2023-10-03 Thread Avi Gross
Just pointing out that if you do not want to SEE an error message that is
otherwise harmless, one option in R is to let the error happen but arrange
to deal with it in some way including just suppressing the message.

On Tue, Oct 3, 2023, 5:27 AM Duncan Murdoch 
wrote:

> On 02/10/2023 10:17 p.m., Trevor Davis wrote:
> >  > Thanks!  However, isn't length(dev.list()) == 0 when there are no
> > devices?  That's what I'm seeing on MacOS.
> >
> > Ifthere is only one graphics device then R should automatically set it
> > as the active graphics device so it isn't really necessary to manually
> > set it.  Although there wouldn't be any harm in manually setting it you
> > only really need to worry about setting the previous graphics device
> > when there are two or more devices open.
>
> Right, I see.  With some more fiddling, I've decided that I don't like
> the error you get if you try to close device 1, so here's the current
> version:
>
> safe.dev.off  <- function(which = dev.cur(), prev = dev.prev()) {
>if (which != 1) {
>  force(prev)
>  grDevices::dev.off(which)
>}
>if (length(dev.list()))
>  dev.set(prev)
>else
>  c("null device" = 1)
> }
>
> This does the dev.set even if there's only one device so it can return
> the resulting device number.
>
> Duncan Murdoch
>
> >
> > Trevor
> >
> > On Mon, Oct 2, 2023 at 5:25 PM Duncan Murdoch  > > wrote:
> >
> > Thanks!  However, isn't length(dev.list()) == 0 when there are no
> > devices?  That's what I'm seeing on MacOS.
> >
> > Duncan Murdoch
> >
> > On 02/10/2023 4:21 p.m., Trevor Davis wrote:
> >  >  > Use it just like dev.off(), but it *will* restore the previous
> > device.
> >  >
> >  > I'm observing that if there were no previously open graphics
> devices
> >  > then your `safe.dev.off()` opens up a new graphics device which
> > may be
> >  > an undesired side effect (because "surprisingly" `dev.set()` on
> > the null
> >  > graphics device opens up a new graphics device).  To avoid that
> you
> >  > could check if `dev.list()` is greater than length 1L:
> >  >
> >  > safe.dev.off  <- function(which = dev.cur(), prev =
> dev.prev()) {
> >  >   force(prev)
> >  >   dev.off(which)
> >  >   if (length(dev.list()) > 1L) {
> >  > dev.set(prev)
> >  >   }
> >  > }
> >  >
> >  > Trevor
> >  >
> >  > On Mon, Oct 2, 2023 at 11:54 AM Duncan Murdoch
> > mailto:murdoch.dun...@gmail.com>
> >  >  > >> wrote:
> >  >
> >  > I found some weird behaviour and reported it as
> >  > https://bugs.r-project.org/show_bug.cgi?id=18604
> > 
> >  >  > > and
> >  > https://github.com/yihui/knitr/issues/2297
> > 
> >  >  > >, but it turns out it
> >  > was user
> >  > error.
> >  >
> >  > The dev.off() function was behaving as documented, but it
> > behaves in an
> >  > unexpected (by me) way, and that caused the "bugs".
> >  >
> >  > The issue is that
> >  >
> >  >  dev.off()
> >  >
> >  > doesn't always result in the previous graphics device being
> made
> >  > current.  If there are two or more other open graphics
> > devices, it
> >  > won't
> >  > choose the previous one, it will choose the next one.
> >  >
> >  > I'm letting people know because this might affect other
> > people too.  If
> >  > you use dev.off(), don't assume it restores the previous
> device!
> >  >
> >  > Here's my little workaround alternative:
> >  >
> >  > safe.dev.off  <- function(which = dev.cur(), prev =
> > dev.prev()) {
> >  >   force(prev)
> >  >   dev.off(which)
> >  >   dev.set(prev)
> >  > }
> >  >
> >  > Use it just like dev.off(), but it *will* restore the
> > previous device.
> >  >
> >  > Duncan Murdoch
> >  >
> >  > __
> >  > R-devel@r-project.org 
> > >
> > mailing list
> >  > https://stat.ethz.ch/mailman/listinfo/r-devel
> > 
> >  >  > >
> >  >
> >
>
> __
> R-devel@r-project.org mailing list
>