@@ -80,8 +80,6 @@ const PYTHON_KEYWORDS = new Set([
8080
8181const MAX_IMPORT_LINE_LENGTH = 100 ;
8282
83- const GENERIC_COMPLEX_TYPES = new Set ( [ "Coding" , "CodeableConcept" ] ) ;
84-
8583const GENERIC_FIELD_REWRITES : Record < string , Record < string , string > > = {
8684 Coding : { code : "T" } ,
8785 CodeableConcept : { coding : "Coding[T]" } ,
@@ -159,8 +157,6 @@ export class Python extends Writer<PythonGeneratorOptions> {
159157 private tsIndex : TypeSchemaIndex | undefined ;
160158 private readonly forFhirpyClient : boolean ;
161159 private readonly fieldFormat : StringFormatKey ;
162- private currentSchemaName : string | undefined ;
163-
164160 constructor ( options : PythonGeneratorOptions ) {
165161 super ( { ...options , resolveAssets : options . resolveAssets ?? resolvePyAssets } ) ;
166162 this . nameFormatFunction = this . getFieldFormatFunction ( options . fieldFormat ) ;
@@ -260,7 +256,7 @@ export class Python extends Writer<PythonGeneratorOptions> {
260256 }
261257
262258 private generateBasePy ( packageComplexTypes : RegularTypeSchema [ ] ) : void {
263- const hasGenericTypes = packageComplexTypes . some ( ( s ) => GENERIC_COMPLEX_TYPES . has ( s . identifier . name ) ) ;
259+ const hasGenericTypes = packageComplexTypes . some ( ( s ) => s . identifier . name in GENERIC_FIELD_REWRITES ) ;
264260 this . cat ( "base.py" , ( ) => {
265261 this . generateDisclaimer ( ) ;
266262 this . generateDefaultImports ( hasGenericTypes ) ;
@@ -392,7 +388,7 @@ export class Python extends Writer<PythonGeneratorOptions> {
392388 private generateResourceModule ( schema : RegularTypeSchema ) : void {
393389 this . cat ( `${ snakeCase ( schema . identifier . name ) } .py` , ( ) => {
394390 this . generateDisclaimer ( ) ;
395- this . generateDefaultImports ( ) ;
391+ this . generateDefaultImports ( false ) ;
396392 this . generateFhirBaseModelImport ( ) ;
397393 this . line ( ) ;
398394 this . generateDependenciesImports ( schema ) ;
@@ -420,33 +416,30 @@ export class Python extends Writer<PythonGeneratorOptions> {
420416 }
421417
422418 private getSuperClasses ( schema : RegularTypeSchema ) : string [ ] {
423- const bases = [ ... ( schema . base ? [ schema . base . name ] : [ ] ) , ... this . injectSuperClasses ( schema . identifier . url ) ] ;
424- if ( GENERIC_COMPLEX_TYPES . has ( schema . identifier . name ) ) {
425- bases . push ( "Generic[T]" ) ;
426- }
419+ const bases : string [ ] = [ ] ;
420+ if ( schema . base ) bases . push ( schema . base . name ) ;
421+ bases . push ( ... this . injectSuperClasses ( schema . identifier . url ) ) ;
422+ if ( schema . identifier . name in GENERIC_FIELD_REWRITES ) bases . push ( "Generic[T]" ) ;
427423 return bases ;
428424 }
429425
430426 private generateClassBody ( schema : RegularTypeSchema ) : void {
431- this . currentSchemaName = schema . identifier . name ;
432427 this . generateModelConfig ( ) ;
433428
434429 if ( ! schema . fields ) {
435430 this . line ( "pass" ) ;
436- this . currentSchemaName = undefined ;
437431 return ;
438432 }
439433
440434 if ( schema . identifier . kind === "resource" ) {
441435 this . generateResourceTypeField ( schema ) ;
442436 }
443437
444- this . generateFields ( schema ) ;
438+ this . generateFields ( schema , schema . identifier . name ) ;
445439
446440 if ( schema . identifier . kind === "resource" ) {
447441 this . generateResourceMethods ( schema ) ;
448442 }
449- this . currentSchemaName = undefined ;
450443 }
451444
452445 private generateModelConfig ( ) : void {
@@ -476,20 +469,20 @@ export class Python extends Writer<PythonGeneratorOptions> {
476469 this . line ( ")" ) ;
477470 }
478471
479- private generateFields ( schema : RegularTypeSchema ) : void {
472+ private generateFields ( schema : RegularTypeSchema , schemaName : string ) : void {
480473 const sortedFields = Object . entries ( schema . fields ?? [ ] ) . sort ( ( [ a ] , [ b ] ) => a . localeCompare ( b ) ) ;
481474
482475 for ( const [ fieldName , field ] of sortedFields ) {
483476 if ( "choices" in field && field . choices ) continue ;
484477
485- const fieldInfo = this . buildFieldInfo ( fieldName , field ) ;
478+ const fieldInfo = this . buildFieldInfo ( fieldName , field , schemaName ) ;
486479 this . line ( `${ fieldInfo . name } : ${ fieldInfo . type } ${ fieldInfo . defaultValue } ` ) ;
487480 }
488481 }
489482
490- private buildFieldInfo ( fieldName : string , field : Field ) : FieldInfo {
483+ private buildFieldInfo ( fieldName : string , field : Field , schemaName : string ) : FieldInfo {
491484 const pyFieldName = fixReservedWords ( this . nameFormatFunction ( fieldName ) ) ;
492- const fieldType = this . determineFieldType ( field , fieldName ) ;
485+ const fieldType = this . determineFieldType ( field , fieldName , schemaName ) ;
493486 const defaultValue = this . getFieldDefaultValue ( field , fieldName ) ;
494487
495488 return {
@@ -499,23 +492,21 @@ export class Python extends Writer<PythonGeneratorOptions> {
499492 } ;
500493 }
501494
502- private determineFieldType ( field : Field , fieldName ? : string ) : string {
495+ private determineFieldType ( field : Field , fieldName : string , schemaName : string ) : string {
503496 let fieldType = field ? this . getBaseFieldType ( field ) : "" ;
504497
505498 // Check for generic type field rewrites (e.g., Coding.code → T, CodeableConcept.coding → Coding[T])
506- if ( this . currentSchemaName && fieldName ) {
507- const rewrite = GENERIC_FIELD_REWRITES [ this . currentSchemaName ] ?. [ fieldName ] ;
508- if ( rewrite ) {
509- fieldType = rewrite ;
510- if ( field . array ) fieldType = `PyList[${ fieldType } ]` ;
511- if ( ! field . required ) fieldType = `${ fieldType } | None` ;
512- return fieldType ;
513- }
499+ const rewrite = GENERIC_FIELD_REWRITES [ schemaName ] ?. [ fieldName ] ;
500+ if ( rewrite ) {
501+ fieldType = rewrite ;
502+ if ( field . array ) fieldType = `PyList[${ fieldType } ]` ;
503+ if ( ! field . required ) fieldType = `${ fieldType } | None` ;
504+ return fieldType ;
514505 }
515506
516507 if ( "enum" in field && field . enum ) {
517508 const baseTypeName = "type" in field ? field . type . name : "" ;
518- if ( GENERIC_COMPLEX_TYPES . has ( baseTypeName ) ) {
509+ if ( baseTypeName in GENERIC_FIELD_REWRITES ) {
519510 fieldType = `${ fieldType } [${ pyEnumType ( field . enum ) } ]` ;
520511 } else if ( ! field . enum . isOpen ) {
521512 const s : string = field . enum . values . map ( ( e : string ) => `"${ e } "` ) . join ( ", " ) ;
@@ -576,7 +567,7 @@ export class Python extends Writer<PythonGeneratorOptions> {
576567 }
577568 }
578569
579- private generateDefaultImports ( includeGenericImports = false ) : void {
570+ private generateDefaultImports ( includeGenericImports : boolean ) : void {
580571 this . pyImportFrom ( "__future__" , "annotations" ) ;
581572 this . pyImportFrom ( "pydantic" , "BaseModel" , "ConfigDict" , "Field" , "PositiveInt" ) ;
582573 const typingImports = [ "List as PyList" , "Literal" ] ;
0 commit comments