{"record":{"id":"46c8ace7024771db","repo":"sgl-project/sglang","slug":"subclasses-of-basescheduler-must-define-attr-p","errorCode":null,"errorMessage":"Subclasses of BaseScheduler must define '{attr}' property","messagePattern":"Subclasses of BaseScheduler must define '(.+?)' property","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/schedulers/base.py","lineNumber":21,"sourceCode":"# SPDX-License-Identifier: Apache-2.0\n\nfrom abc import ABC, abstractmethod\n\nimport torch\n\n\nclass BaseScheduler(ABC):\n    timesteps: torch.Tensor\n    order: int\n    num_train_timesteps: int\n\n    def __init__(self, *args, **kwargs) -> None:\n        # Check if subclass has defined all required properties\n        required_attributes = [\"timesteps\", \"order\", \"num_train_timesteps\"]\n\n        for attr in required_attributes:\n            if not hasattr(self, attr):\n                raise AttributeError(\n                    f\"Subclasses of BaseScheduler must define '{attr}' property\"\n                )\n\n    @abstractmethod\n    def set_shift(self, shift: float) -> None:\n        pass\n\n    @abstractmethod\n    def set_timesteps(self, *args, **kwargs) -> None:\n        pass\n\n    @abstractmethod\n    def scale_model_input(\n        self, sample: torch.Tensor, timestep: int | None = None\n    ) -> torch.Tensor:\n        pass\n","sourceCodeStart":3,"sourceCodeEnd":38,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/schedulers/base.py#L3-L38","documentation":"BaseScheduler.__init__ enforces that every subclass defines the properties timesteps, order, and num_train_timesteps (typically as @property). If a subclass sets none of them in __init__ and does not define the properties, the abstract-contract check raises AttributeError immediately at construction.","triggerScenarios":"Subclassing BaseScheduler (e.g. a custom flow-match scheduler) and overriding __init__ without calling super().__init__() AFTER setting self.timesteps/etc., or simply not defining the three properties/attributes at all.","commonSituations":"Writing a custom scheduler for a new diffusion model; refactoring an existing scheduler so timesteps becomes a lazily-computed property and the attribute is removed; forgetting super().__init__() ordering (check runs before attributes exist if super is called first).","solutions":["Define timesteps, order, and num_train_timesteps as attributes or @property on the subclass","Call super().__init__() AFTER assigning the required attributes in the subclass __init__ (the check uses hasattr on self)","Initialize them to None only if the property is defined — a plain missing attribute will fail; prefer explicit property definitions","Add a quick construction smoke test for each new scheduler"],"exampleFix":"// before\nclass MySched(BaseScheduler):\n    def __init__(self):\n        super().__init__()  # fails: attrs not set yet\n        self.num_train_timesteps = 1000\n// after\nclass MySched(BaseScheduler):\n    num_train_timesteps: int = 1000\n    order = 1\n    def __init__(self):\n        self.timesteps = None\n        super().__init__()","handlingStrategy":"type-guard","validationCode":"required = {'timesteps', 'order', 'num_train_timesteps'}\nassert all(hasattr(sched, a) for a in required), f'scheduler missing: {required - set(dir(sched))}'","typeGuard":"def satisfies_base_scheduler(s: type) -> bool:\n    return all(any(a in vars(c) for c in s.__mro__) for a in ('timesteps', 'order', 'num_train_timesteps'))","tryCatchPattern":"try:\n    sched = MyScheduler(...)\nexcept AttributeError as e:\n    raise TypeError(f'{type(sched).__name__} incomplete BaseScheduler impl') from e","preventionTips":["Set required attributes before calling super().__init__() in subclass __init__","Define the three as @property so the contract is always satisfiable","Add a construction smoke test per scheduler subclass"],"tags":["scheduler","abstract-base","subclass-contract","diffusion"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}