@@ -376,3 +376,174 @@ def exports(check_all: bool, package: Optional[str]):
376
376
except Exception as e :
377
377
click .echo (f"Error: { e } " , err = True )
378
378
sys .exit (1 )
379
+
380
+
381
+ @check .command ("exclude-lists" )
382
+ @click .option (
383
+ "--missing-public" ,
384
+ "check_missing_public" ,
385
+ is_flag = True ,
386
+ help = "Audit EXCLUDE_MISSING_PUBLIC list for symbols that now have @public decorators" ,
387
+ )
388
+ @click .option (
389
+ "--missing-rst" ,
390
+ "check_missing_rst" ,
391
+ is_flag = True ,
392
+ help = "Audit EXCLUDE_MISSING_RST list for symbols that now have RST documentation" ,
393
+ )
394
+ @click .option (
395
+ "--missing-export" ,
396
+ "check_missing_export" ,
397
+ is_flag = True ,
398
+ help = "Audit EXCLUDE_MISSING_EXPORT list for symbols that are now exported at top-level" ,
399
+ )
400
+ def exclude_lists (check_missing_public : bool , check_missing_rst : bool , check_missing_export : bool ):
401
+ """Audit exclude lists to ensure entries are still necessary."""
402
+ if not any ([check_missing_public , check_missing_rst , check_missing_export ]):
403
+ click .echo ("Error: Must specify at least one exclude list to check" , err = True )
404
+ sys .exit (1 )
405
+
406
+ dagster_root = _find_dagster_root ()
407
+ if dagster_root is None :
408
+ click .echo ("Error: Could not find dagster repository root" , err = True )
409
+ sys .exit (1 )
410
+
411
+ try :
412
+ validator = PublicApiValidator (dagster_root )
413
+ exit_codes = []
414
+
415
+ if check_missing_public :
416
+ exit_codes .append (_audit_exclude_missing_public (validator ))
417
+
418
+ if check_missing_rst :
419
+ if exit_codes : # Add separator if we already printed something
420
+ click .echo ("\n " + "=" * 80 + "\n " )
421
+ exit_codes .append (_audit_exclude_missing_rst (validator ))
422
+
423
+ if check_missing_export :
424
+ if exit_codes : # Add separator if we already printed something
425
+ click .echo ("\n " + "=" * 80 + "\n " )
426
+ exit_codes .append (_audit_exclude_missing_export (validator ))
427
+
428
+ # Exit with 1 if any audit found issues, 0 otherwise
429
+ sys .exit (1 if any (exit_codes ) else 0 )
430
+
431
+ except Exception as e :
432
+ click .echo (f"Error: { e } " , err = True )
433
+ sys .exit (1 )
434
+
435
+
436
+ def _audit_exclude_missing_public (validator : PublicApiValidator ) -> int :
437
+ """Audit EXCLUDE_MISSING_PUBLIC list for symbols that now have @public decorators.
438
+
439
+ Returns:
440
+ 0 if all entries are still valid, 1 if some entries can be removed
441
+ """
442
+ # Get all symbols that have @public decorators
443
+ public_symbols = validator .find_public_symbols (exclude_modules = EXCLUDE_MODULES_FROM_PUBLIC_SCAN )
444
+ public_lookup = {f"{ sym .module_path } .{ sym .symbol_name } " for sym in public_symbols }
445
+
446
+ # Check which symbols in EXCLUDE_MISSING_PUBLIC actually have @public decorators now
447
+ symbols_with_public = []
448
+ for symbol_path in EXCLUDE_MISSING_PUBLIC :
449
+ if symbol_path in public_lookup :
450
+ symbols_with_public .append (symbol_path )
451
+
452
+ if not symbols_with_public :
453
+ click .echo (
454
+ "✓ All entries in EXCLUDE_MISSING_PUBLIC are still valid (symbols still missing @public decorators)"
455
+ )
456
+ return 0
457
+
458
+ click .echo (
459
+ f"Found { len (symbols_with_public )} symbols in EXCLUDE_MISSING_PUBLIC that now have @public decorators:"
460
+ )
461
+ click .echo ("These entries can be removed from the exclude list:" )
462
+ click .echo ()
463
+
464
+ for symbol_path in sorted (symbols_with_public ):
465
+ click .echo (f" { symbol_path } " )
466
+
467
+ click .echo ()
468
+ click .echo ("To remove these entries, edit:" )
469
+ click .echo (" python_modules/automation/automation/docstring_lint/exclude_lists.py" )
470
+
471
+ return 1
472
+
473
+
474
+ def _audit_exclude_missing_rst (validator : PublicApiValidator ) -> int :
475
+ """Audit EXCLUDE_MISSING_RST list for symbols that now have RST documentation.
476
+
477
+ Returns:
478
+ 0 if all entries are still valid, 1 if some entries can be removed
479
+ """
480
+ # Get all symbols documented in RST files
481
+ rst_symbols = validator .find_rst_documented_symbols (exclude_files = EXCLUDE_RST_FILES )
482
+ rst_lookup = {f"{ sym .module_path } .{ sym .symbol_name } " for sym in rst_symbols }
483
+
484
+ # Check which symbols in EXCLUDE_MISSING_RST actually have RST documentation now
485
+ symbols_with_rst = []
486
+ for symbol_path in EXCLUDE_MISSING_RST :
487
+ if symbol_path in rst_lookup :
488
+ symbols_with_rst .append (symbol_path )
489
+
490
+ if not symbols_with_rst :
491
+ click .echo (
492
+ "✓ All entries in EXCLUDE_MISSING_RST are still valid (symbols still missing RST documentation)"
493
+ )
494
+ return 0
495
+
496
+ click .echo (
497
+ f"Found { len (symbols_with_rst )} symbols in EXCLUDE_MISSING_RST that now have RST documentation:"
498
+ )
499
+ click .echo ("These entries can be removed from the exclude list:" )
500
+ click .echo ()
501
+
502
+ for symbol_path in sorted (symbols_with_rst ):
503
+ click .echo (f" { symbol_path } " )
504
+
505
+ click .echo ()
506
+ click .echo ("To remove these entries, edit:" )
507
+ click .echo (" python_modules/automation/automation/docstring_lint/exclude_lists.py" )
508
+
509
+ return 1
510
+
511
+
512
+ def _audit_exclude_missing_export (validator : PublicApiValidator ) -> int :
513
+ """Audit EXCLUDE_MISSING_EXPORT list for symbols that are now exported at top-level.
514
+
515
+ Returns:
516
+ 0 if all entries are still valid, 1 if some entries can be removed
517
+ """
518
+ # Get all symbols that have @public decorators and check their export status
519
+ public_symbols = validator .find_public_symbols (exclude_modules = EXCLUDE_MODULES_FROM_PUBLIC_SCAN )
520
+ exported_lookup = {
521
+ f"{ sym .module_path } .{ sym .symbol_name } " for sym in public_symbols if sym .is_exported
522
+ }
523
+
524
+ # Check which symbols in EXCLUDE_MISSING_EXPORT are actually exported now
525
+ symbols_with_export = []
526
+ for symbol_path in EXCLUDE_MISSING_EXPORT :
527
+ if symbol_path in exported_lookup :
528
+ symbols_with_export .append (symbol_path )
529
+
530
+ if not symbols_with_export :
531
+ click .echo (
532
+ "✓ All entries in EXCLUDE_MISSING_EXPORT are still valid (symbols still not exported at top-level)"
533
+ )
534
+ return 0
535
+
536
+ click .echo (
537
+ f"Found { len (symbols_with_export )} symbols in EXCLUDE_MISSING_EXPORT that are now exported at top-level:"
538
+ )
539
+ click .echo ("These entries can be removed from the exclude list:" )
540
+ click .echo ()
541
+
542
+ for symbol_path in sorted (symbols_with_export ):
543
+ click .echo (f" { symbol_path } " )
544
+
545
+ click .echo ()
546
+ click .echo ("To remove these entries, edit:" )
547
+ click .echo (" python_modules/automation/automation/docstring_lint/exclude_lists.py" )
548
+
549
+ return 1
0 commit comments