OpenAPITools / OpenAPITools/openapi-generator
[BUG][R] anyOf/oneOf models break on primitive types
Nobody has claimed this yet.
- 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
- Ran ./bin/generate-samples.sh bin/configs/r-client.yaml
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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