OpenAPITools / OpenAPITools/openapi-generator

[BUG][R] anyOf/oneOf models break on primitive types

Open
#13,556 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

The anyOf/oneOf model template files for the R client generator will generate invalid R code when working with a component schema that includes anyOf / oneOf types that handle primitives.

> aop <- AnyOfPrimitiveTypeTest$new(instance = 4L) # an integer
Error in get(class(instance)[[1]], pos = -1)$classname : 
  object of type 'closure' is not subsettable

> aop <- AnyOfPrimitiveTypeTest$new()
> aop$actual_instance <- 4L # an integer
> aop$actual_type <- "integer"

> aop # calls print
Error in self$actual_instance$toJSONString : 
$ operator is invalid for atomic vectors

> aop$toJSON()
Error in self$actual_instance$toJSON : 
  $ operator is invalid for atomic vectors

> aop$toJSONString()
 Error in self$actual_instance$toJSONString : 
$ operator is invalid for atomic vectors

Generally speaking, the templates are written assuming that get(class(instance)[[1]], pos = -1) returns an R6 object generator and that actual_instance is an R6 object. When the underlying OpenAPI spec uses primitive types, these assumptions break.

openapi-generator version

Tested with 6.2.1-SNAPSHOT, master (210a394e0dfed86a845b31a7d32b82ba45d0a2c7)

OpenAPI declaration file content or url

Happens with the existing modules/openapi-generator/src/test/resources/3_0/r/petstore.yaml. You can review the AnyOfPrimitiveTest and OneOfPrimitiveTypeTest class definitions.

Generation Details

No additional options beyond those set by ./bin/generate-samples.sh.

Reproduced in R 3.6.3 and 4.1.2.

Steps to reproduce
  1. Ran ./bin/generate-samples.sh bin/configs/r-client.yaml
  2. In an R session,
source("samples/client/petstore/R/R/any_of_primitive_type_test.R")
aop <- AnyOfPrimitiveTypeTest$new(instance = "stringtest") # character
# fails
aop <- AnyOfPrimitiveTypeTest$new(instance = 4L) # integer
# fails
Related issues/PRs

https://github.com/OpenAPITools/openapi-generator/issues/13538

Suggest a fix

If the general idea for the R client is to build objects for any composed schemas, then we should conditionally output code validating the object class type based on whether isPrimitiveType is true. There's plenty of this in modelGeneric.mustache.

For example, in the initialize() function, something like:

if (is.null(instance)) {
        # do nothing
      } else if (is.character(instance)) {
        self$actual_instance <- instance
        self$actual_type <- "character"
      } else if (is.integer(instance)) {
        self$actual_instance <- instance
        self$actual_type <- "integer"
      } else {
        stop(paste("Failed to initialize AnyOfPrimitiveTypeTest with oneOf schemas character, integer. Provided class name: ",
                   class(instance)))
      }

With similar checks in the other R6 class functions, and with consideration for the possibility that anyOf/oneOf may refer to "mixed" types, i.e. one Complex and one Primitive.

It would also be nice to not have to create an entirely separate class definition in R for these schemas, since they are going to be primitives anyway and deserialization with the jsonlite::fromJSON() function works quite well, but that's an architectural discussion.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with modelGeneric.mustache and the generated samples/client/petstore/R/R/any_of_primitive_type_test.R, then inspect the AnyOfPrimitiveTest and OneOfPrimitiveTypeTest definitions from petstore.yaml. Run ./bin/generate-samples.sh bin/configs/r-client.yaml and reproduce the R errors with character and integer instances. Done means generated R code handles primitive anyOf/oneOf values without treating them as R6 objects, including the mixed primitive/complex case described.

Written by the indexing model from the issue text.

Assessment

Tech stack
r
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.