utils::isS3stdGeneric chokes on primitives and identity

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

utils::isS3stdGeneric chokes on primitives and identity

Antoine Fabri
Dear R-devel,

utils::isS3stdGeneric tries to subset the body of the function it's fed,
primitives don't like that because they don't have a body, identity doesn't
like it either because it's body is a symbol.

According to the doc, any function is a legal input.

See below:

identity
#> function (x)
#> x
#> <bytecode: 0x0000000013d6da28>
#> <environment: namespace:base>

max
#> function (..., na.rm = FALSE)  .Primitive("max")

isS3stdGeneric(identity)
#> Error in bdexpr[[1L]]: objet de type 'symbol' non indiçable

isS3stdGeneric(max)
#> Error in while (as.character(bdexpr[[1L]]) == "{") bdexpr <-
bdexpr[[2L]]: l'argument est de longueur nulle

Here is a simple fix :

isS3stdGeneric <- function(f) {
  {
    bdexpr <- body(f)
    if(is.null(bdexpr) || !is.call(bdexpr)) return(FALSE)
    while (as.character(bdexpr[[1L]]) == "{") bdexpr <- bdexpr[[2L]]
    ret <- is.call(bdexpr) && identical(bdexpr[[1L]], as.name("UseMethod"))
    if (ret)
      names(ret) <- bdexpr[[2L]]
    ret
  }
}

isS3stdGeneric(identity)
#> [1] FALSE
isS3stdGeneric(max)
#> [1] FALSE

Best,

Antoine

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: utils::isS3stdGeneric chokes on primitives and identity

Gabriel Becker-2
I added that so I can look at the proposed fix and put it or something
similar in bugzilla for review final review.

Apologies for the oversight.

~G

On Wed, Aug 19, 2020 at 3:40 PM Antoine Fabri <[hidden email]>
wrote:

> Dear R-devel,
>
> utils::isS3stdGeneric tries to subset the body of the function it's fed,
> primitives don't like that because they don't have a body, identity doesn't
> like it either because it's body is a symbol.
>
> According to the doc, any function is a legal input.
>
> See below:
>
> identity
> #> function (x)
> #> x
> #> <bytecode: 0x0000000013d6da28>
> #> <environment: namespace:base>
>
> max
> #> function (..., na.rm = FALSE)  .Primitive("max")
>
> isS3stdGeneric(identity)
> #> Error in bdexpr[[1L]]: objet de type 'symbol' non indiçable
>
> isS3stdGeneric(max)
> #> Error in while (as.character(bdexpr[[1L]]) == "{") bdexpr <-
> bdexpr[[2L]]: l'argument est de longueur nulle
>
> Here is a simple fix :
>
> isS3stdGeneric <- function(f) {
>   {
>     bdexpr <- body(f)
>     if(is.null(bdexpr) || !is.call(bdexpr)) return(FALSE)
>     while (as.character(bdexpr[[1L]]) == "{") bdexpr <- bdexpr[[2L]]
>     ret <- is.call(bdexpr) && identical(bdexpr[[1L]], as.name
> ("UseMethod"))
>     if (ret)
>       names(ret) <- bdexpr[[2L]]
>     ret
>   }
> }
>
> isS3stdGeneric(identity)
> #> [1] FALSE
> isS3stdGeneric(max)
> #> [1] FALSE
>
> Best,
>
> Antoine
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: utils::isS3stdGeneric chokes on primitives and identity

Kurt Hornik-5
>>>>> Gabriel Becker writes:

> I added that so I can look at the proposed fix and put it or something
> similar in bugzilla for review final review.

> Apologies for the oversight.

Fixed now with

-    while(as.character(bdexpr[[1L]]) == "{")
+    while(is.call(bdexpr) && (as.character(bdexpr[[1L]]) == "{"))

(the suggested fix does not work on things like
foo <- function(x) {{ x }}
...)

Best
-k

> ~G

> On Wed, Aug 19, 2020 at 3:40 PM Antoine Fabri <[hidden email]>
> wrote:

>> Dear R-devel,
>>
>> utils::isS3stdGeneric tries to subset the body of the function it's fed,
>> primitives don't like that because they don't have a body, identity doesn't
>> like it either because it's body is a symbol.
>>
>> According to the doc, any function is a legal input.
>>
>> See below:
>>
>> identity
>> #> function (x)
>> #> x
>> #> <bytecode: 0x0000000013d6da28>
>> #> <environment: namespace:base>
>>
>> max
>> #> function (..., na.rm = FALSE)  .Primitive("max")
>>
>> isS3stdGeneric(identity)
>> #> Error in bdexpr[[1L]]: objet de type 'symbol' non indiçable
>>
>> isS3stdGeneric(max)
>> #> Error in while (as.character(bdexpr[[1L]]) == "{") bdexpr <-
>> bdexpr[[2L]]: l'argument est de longueur nulle
>>
>> Here is a simple fix :
>>
>> isS3stdGeneric <- function(f) {
>> {
>> bdexpr <- body(f)
>> if(is.null(bdexpr) || !is.call(bdexpr)) return(FALSE)
>> while (as.character(bdexpr[[1L]]) == "{") bdexpr <- bdexpr[[2L]]
>> ret <- is.call(bdexpr) && identical(bdexpr[[1L]], as.name
>> ("UseMethod"))
>> if (ret)
>> names(ret) <- bdexpr[[2L]]
>> ret
>> }
>> }
>>
>> isS3stdGeneric(identity)
>> #> [1] FALSE
>> isS3stdGeneric(max)
>> #> [1] FALSE
>>
>> Best,
>>
>> Antoine
>>
>> [[alternative HTML version deleted]]
>>
>> ______________________________________________
>> [hidden email] mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>

> [[alternative HTML version deleted]]

> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: utils::isS3stdGeneric chokes on primitives and identity

Antoine Fabri
Should it work on traced functions ?

As it is now it doesn't.

Best,

Antoine

Le jeu. 20 août 2020 à 09:58, Kurt Hornik <[hidden email]> a écrit :

> >>>>> Gabriel Becker writes:
>
> > I added that so I can look at the proposed fix and put it or something
> > similar in bugzilla for review final review.
>
> > Apologies for the oversight.
>
> Fixed now with
>
> -    while(as.character(bdexpr[[1L]]) == "{")
> +    while(is.call(bdexpr) && (as.character(bdexpr[[1L]]) == "{"))
>
> (the suggested fix does not work on things like
> foo <- function(x) {{ x }}
> ...)
>
> Best
> -k
>
> > ~G
>
> > On Wed, Aug 19, 2020 at 3:40 PM Antoine Fabri <[hidden email]>
> > wrote:
>
> >> Dear R-devel,
> >>
> >> utils::isS3stdGeneric tries to subset the body of the function it's fed,
> >> primitives don't like that because they don't have a body, identity
> doesn't
> >> like it either because it's body is a symbol.
> >>
> >> According to the doc, any function is a legal input.
> >>
> >> See below:
> >>
> >> identity
> >> #> function (x)
> >> #> x
> >> #> <bytecode: 0x0000000013d6da28>
> >> #> <environment: namespace:base>
> >>
> >> max
> >> #> function (..., na.rm = FALSE)  .Primitive("max")
> >>
> >> isS3stdGeneric(identity)
> >> #> Error in bdexpr[[1L]]: objet de type 'symbol' non indiçable
> >>
> >> isS3stdGeneric(max)
> >> #> Error in while (as.character(bdexpr[[1L]]) == "{") bdexpr <-
> >> bdexpr[[2L]]: l'argument est de longueur nulle
> >>
> >> Here is a simple fix :
> >>
> >> isS3stdGeneric <- function(f) {
> >> {
> >> bdexpr <- body(f)
> >> if(is.null(bdexpr) || !is.call(bdexpr)) return(FALSE)
> >> while (as.character(bdexpr[[1L]]) == "{") bdexpr <- bdexpr[[2L]]
> >> ret <- is.call(bdexpr) && identical(bdexpr[[1L]], as.name
> >> ("UseMethod"))
> >> if (ret)
> >> names(ret) <- bdexpr[[2L]]
> >> ret
> >> }
> >> }
> >>
> >> isS3stdGeneric(identity)
> >> #> [1] FALSE
> >> isS3stdGeneric(max)
> >> #> [1] FALSE
> >>
> >> Best,
> >>
> >> Antoine
> >>
> >> [[alternative HTML version deleted]]
> >>
> >> ______________________________________________
> >> [hidden email] mailing list
> >> https://stat.ethz.ch/mailman/listinfo/r-devel
> >>
>
> >       [[alternative HTML version deleted]]
>
> > ______________________________________________
> > [hidden email] mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: utils::isS3stdGeneric chokes on primitives and identity

Gabriel Becker-2
Trace adds something to the body of the function, so it does make sense
that it doesn't. Whether traced functions still technically meet the
definition of standard s3 generic or not is, I suppose, up for debate, but
I would say that they should, I think.

As before, if desired I can work on a patch for this if desired, or someone
on R-core can just take care of it if that is easier.

Best,
~G

On Thu, Aug 27, 2020 at 11:22 AM Antoine Fabri <[hidden email]>
wrote:

> Should it work on traced functions ?
>
> As it is now it doesn't.
>
> Best,
>
> Antoine
>
> Le jeu. 20 août 2020 à 09:58, Kurt Hornik <[hidden email]> a écrit :
>
>> >>>>> Gabriel Becker writes:
>>
>> > I added that so I can look at the proposed fix and put it or something
>> > similar in bugzilla for review final review.
>>
>> > Apologies for the oversight.
>>
>> Fixed now with
>>
>> -    while(as.character(bdexpr[[1L]]) == "{")
>> +    while(is.call(bdexpr) && (as.character(bdexpr[[1L]]) == "{"))
>>
>> (the suggested fix does not work on things like
>> foo <- function(x) {{ x }}
>> ...)
>>
>> Best
>> -k
>>
>> > ~G
>>
>> > On Wed, Aug 19, 2020 at 3:40 PM Antoine Fabri <[hidden email]>
>> > wrote:
>>
>> >> Dear R-devel,
>> >>
>> >> utils::isS3stdGeneric tries to subset the body of the function it's
>> fed,
>> >> primitives don't like that because they don't have a body, identity
>> doesn't
>> >> like it either because it's body is a symbol.
>> >>
>> >> According to the doc, any function is a legal input.
>> >>
>> >> See below:
>> >>
>> >> identity
>> >> #> function (x)
>> >> #> x
>> >> #> <bytecode: 0x0000000013d6da28>
>> >> #> <environment: namespace:base>
>> >>
>> >> max
>> >> #> function (..., na.rm = FALSE)  .Primitive("max")
>> >>
>> >> isS3stdGeneric(identity)
>> >> #> Error in bdexpr[[1L]]: objet de type 'symbol' non indiçable
>> >>
>> >> isS3stdGeneric(max)
>> >> #> Error in while (as.character(bdexpr[[1L]]) == "{") bdexpr <-
>> >> bdexpr[[2L]]: l'argument est de longueur nulle
>> >>
>> >> Here is a simple fix :
>> >>
>> >> isS3stdGeneric <- function(f) {
>> >> {
>> >> bdexpr <- body(f)
>> >> if(is.null(bdexpr) || !is.call(bdexpr)) return(FALSE)
>> >> while (as.character(bdexpr[[1L]]) == "{") bdexpr <- bdexpr[[2L]]
>> >> ret <- is.call(bdexpr) && identical(bdexpr[[1L]], as.name
>> >> ("UseMethod"))
>> >> if (ret)
>> >> names(ret) <- bdexpr[[2L]]
>> >> ret
>> >> }
>> >> }
>> >>
>> >> isS3stdGeneric(identity)
>> >> #> [1] FALSE
>> >> isS3stdGeneric(max)
>> >> #> [1] FALSE
>> >>
>> >> Best,
>> >>
>> >> Antoine
>> >>
>> >> [[alternative HTML version deleted]]
>> >>
>> >> ______________________________________________
>> >> [hidden email] mailing list
>> >> https://stat.ethz.ch/mailman/listinfo/r-devel
>> >>
>>
>> >       [[alternative HTML version deleted]]
>>
>> > ______________________________________________
>> > [hidden email] mailing list
>> > https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: utils::isS3stdGeneric chokes on primitives and identity

Gabriel Becker-2
Hi all,

I have a patch that fixes this and also fixes/improves debugcall so that it
supports pkg::fun(obj) and pkg:::fun(obj) style calls. I'm going to test it
a bit more and add a regression test for isS3stdGeneric and then I will
submit it to bugzilla tonight or tomorrow morning.

Best,
~G

On Thu, Aug 27, 2020 at 5:28 PM Gabriel Becker <[hidden email]>
wrote:

> Trace adds something to the body of the function, so it does make sense
> that it doesn't. Whether traced functions still technically meet the
> definition of standard s3 generic or not is, I suppose, up for debate, but
> I would say that they should, I think.
>
> As before, if desired I can work on a patch for this if desired, or
> someone on R-core can just take care of it if that is easier.
>
> Best,
> ~G
>
> On Thu, Aug 27, 2020 at 11:22 AM Antoine Fabri <[hidden email]>
> wrote:
>
>> Should it work on traced functions ?
>>
>> As it is now it doesn't.
>>
>> Best,
>>
>> Antoine
>>
>> Le jeu. 20 août 2020 à 09:58, Kurt Hornik <[hidden email]> a
>> écrit :
>>
>>> >>>>> Gabriel Becker writes:
>>>
>>> > I added that so I can look at the proposed fix and put it or something
>>> > similar in bugzilla for review final review.
>>>
>>> > Apologies for the oversight.
>>>
>>> Fixed now with
>>>
>>> -    while(as.character(bdexpr[[1L]]) == "{")
>>> +    while(is.call(bdexpr) && (as.character(bdexpr[[1L]]) == "{"))
>>>
>>> (the suggested fix does not work on things like
>>> foo <- function(x) {{ x }}
>>> ...)
>>>
>>> Best
>>> -k
>>>
>>> > ~G
>>>
>>> > On Wed, Aug 19, 2020 at 3:40 PM Antoine Fabri <[hidden email]
>>> >
>>> > wrote:
>>>
>>> >> Dear R-devel,
>>> >>
>>> >> utils::isS3stdGeneric tries to subset the body of the function it's
>>> fed,
>>> >> primitives don't like that because they don't have a body, identity
>>> doesn't
>>> >> like it either because it's body is a symbol.
>>> >>
>>> >> According to the doc, any function is a legal input.
>>> >>
>>> >> See below:
>>> >>
>>> >> identity
>>> >> #> function (x)
>>> >> #> x
>>> >> #> <bytecode: 0x0000000013d6da28>
>>> >> #> <environment: namespace:base>
>>> >>
>>> >> max
>>> >> #> function (..., na.rm = FALSE)  .Primitive("max")
>>> >>
>>> >> isS3stdGeneric(identity)
>>> >> #> Error in bdexpr[[1L]]: objet de type 'symbol' non indiçable
>>> >>
>>> >> isS3stdGeneric(max)
>>> >> #> Error in while (as.character(bdexpr[[1L]]) == "{") bdexpr <-
>>> >> bdexpr[[2L]]: l'argument est de longueur nulle
>>> >>
>>> >> Here is a simple fix :
>>> >>
>>> >> isS3stdGeneric <- function(f) {
>>> >> {
>>> >> bdexpr <- body(f)
>>> >> if(is.null(bdexpr) || !is.call(bdexpr)) return(FALSE)
>>> >> while (as.character(bdexpr[[1L]]) == "{") bdexpr <- bdexpr[[2L]]
>>> >> ret <- is.call(bdexpr) && identical(bdexpr[[1L]], as.name
>>> >> ("UseMethod"))
>>> >> if (ret)
>>> >> names(ret) <- bdexpr[[2L]]
>>> >> ret
>>> >> }
>>> >> }
>>> >>
>>> >> isS3stdGeneric(identity)
>>> >> #> [1] FALSE
>>> >> isS3stdGeneric(max)
>>> >> #> [1] FALSE
>>> >>
>>> >> Best,
>>> >>
>>> >> Antoine
>>> >>
>>> >> [[alternative HTML version deleted]]
>>> >>
>>> >> ______________________________________________
>>> >> [hidden email] mailing list
>>> >> https://stat.ethz.ch/mailman/listinfo/r-devel
>>> >>
>>>
>>> >       [[alternative HTML version deleted]]
>>>
>>> > ______________________________________________
>>> > [hidden email] mailing list
>>> > https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: utils::isS3stdGeneric chokes on primitives and identity

Gabriel Becker-2
Submitted to bugzilla here:
https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17901

On Sat, Aug 29, 2020 at 1:57 PM Gabriel Becker <[hidden email]>
wrote:

> Hi all,
>
> I have a patch that fixes this and also fixes/improves debugcall so that
> it supports pkg::fun(obj) and pkg:::fun(obj) style calls. I'm going to test
> it a bit more and add a regression test for isS3stdGeneric and then I will
> submit it to bugzilla tonight or tomorrow morning.
>
> Best,
> ~G
>
> On Thu, Aug 27, 2020 at 5:28 PM Gabriel Becker <[hidden email]>
> wrote:
>
>> Trace adds something to the body of the function, so it does make sense
>> that it doesn't. Whether traced functions still technically meet the
>> definition of standard s3 generic or not is, I suppose, up for debate, but
>> I would say that they should, I think.
>>
>> As before, if desired I can work on a patch for this if desired, or
>> someone on R-core can just take care of it if that is easier.
>>
>> Best,
>> ~G
>>
>> On Thu, Aug 27, 2020 at 11:22 AM Antoine Fabri <[hidden email]>
>> wrote:
>>
>>> Should it work on traced functions ?
>>>
>>> As it is now it doesn't.
>>>
>>> Best,
>>>
>>> Antoine
>>>
>>> Le jeu. 20 août 2020 à 09:58, Kurt Hornik <[hidden email]> a
>>> écrit :
>>>
>>>> >>>>> Gabriel Becker writes:
>>>>
>>>> > I added that so I can look at the proposed fix and put it or something
>>>> > similar in bugzilla for review final review.
>>>>
>>>> > Apologies for the oversight.
>>>>
>>>> Fixed now with
>>>>
>>>> -    while(as.character(bdexpr[[1L]]) == "{")
>>>> +    while(is.call(bdexpr) && (as.character(bdexpr[[1L]]) == "{"))
>>>>
>>>> (the suggested fix does not work on things like
>>>> foo <- function(x) {{ x }}
>>>> ...)
>>>>
>>>> Best
>>>> -k
>>>>
>>>> > ~G
>>>>
>>>> > On Wed, Aug 19, 2020 at 3:40 PM Antoine Fabri <
>>>> [hidden email]>
>>>> > wrote:
>>>>
>>>> >> Dear R-devel,
>>>> >>
>>>> >> utils::isS3stdGeneric tries to subset the body of the function it's
>>>> fed,
>>>> >> primitives don't like that because they don't have a body, identity
>>>> doesn't
>>>> >> like it either because it's body is a symbol.
>>>> >>
>>>> >> According to the doc, any function is a legal input.
>>>> >>
>>>> >> See below:
>>>> >>
>>>> >> identity
>>>> >> #> function (x)
>>>> >> #> x
>>>> >> #> <bytecode: 0x0000000013d6da28>
>>>> >> #> <environment: namespace:base>
>>>> >>
>>>> >> max
>>>> >> #> function (..., na.rm = FALSE)  .Primitive("max")
>>>> >>
>>>> >> isS3stdGeneric(identity)
>>>> >> #> Error in bdexpr[[1L]]: objet de type 'symbol' non indiçable
>>>> >>
>>>> >> isS3stdGeneric(max)
>>>> >> #> Error in while (as.character(bdexpr[[1L]]) == "{") bdexpr <-
>>>> >> bdexpr[[2L]]: l'argument est de longueur nulle
>>>> >>
>>>> >> Here is a simple fix :
>>>> >>
>>>> >> isS3stdGeneric <- function(f) {
>>>> >> {
>>>> >> bdexpr <- body(f)
>>>> >> if(is.null(bdexpr) || !is.call(bdexpr)) return(FALSE)
>>>> >> while (as.character(bdexpr[[1L]]) == "{") bdexpr <- bdexpr[[2L]]
>>>> >> ret <- is.call(bdexpr) && identical(bdexpr[[1L]], as.name
>>>> >> ("UseMethod"))
>>>> >> if (ret)
>>>> >> names(ret) <- bdexpr[[2L]]
>>>> >> ret
>>>> >> }
>>>> >> }
>>>> >>
>>>> >> isS3stdGeneric(identity)
>>>> >> #> [1] FALSE
>>>> >> isS3stdGeneric(max)
>>>> >> #> [1] FALSE
>>>> >>
>>>> >> Best,
>>>> >>
>>>> >> Antoine
>>>> >>
>>>> >> [[alternative HTML version deleted]]
>>>> >>
>>>> >> ______________________________________________
>>>> >> [hidden email] mailing list
>>>> >> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>> >>
>>>>
>>>> >       [[alternative HTML version deleted]]
>>>>
>>>> > ______________________________________________
>>>> > [hidden email] mailing list
>>>> > https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>
>>>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel