Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adoption of Final Qualifier in SymPy Classes #5

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.vscode
76 changes: 76 additions & 0 deletions SymPEP-X.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# SymPEP X — Adoption of Final Qualifier in SymPy Classes

**Author:** Sangyub Lee

**Status:** Draft

**Type:** Standards Track

**Created:** 2023-08-25

**Resolution:** [Link to Discussion]

## Abstract

This SymPEP proposes the adoption of the `final` qualifier in appropriate SymPy classes to enhance code design, maintainability, and performance. The `final` qualifier restricts subclassing of certain classes, promoting better code structure and reducing potential sources of bugs and inefficiencies.

## Motivation and Scope

In object-oriented programming, the `final` keyword is used to indicate that a class or method cannot be subclassed or overridden in subclasses. Introducing the `final` qualifier in selected SymPy classes will provide several benefits:

- Prevent unintentional subclassing that could lead to fragile inheritance hierarchies.
- Enable the SymPy developers to better control the behavior and design of critical classes.

The scope of this proposal includes identifying classes in SymPy that should be marked as `final` and adding the `final` keyword to their class definitions.

## Usage and Impact

By marking certain classes as `final`, the SymPy developers will signal that these classes are intended to be used as-is and not extended. This will guide users and contributors to understand the intended usage of these classes and avoid subclassing when it's not appropriate. This change will have a positive impact on code stability and reliability, as well as the overall maintenance of the library.

For example:

```python
from typing import final

class Basic:
@final
def doit(self, deep=True):
if deep:
expr = self.func(*(arg.doit(deep=deep) for arg in args))
return expr._eval_doit()
return self._eval_doit()

def _eval_doit(self):
return self
```

In this scenario, the `Basic` class is marked as `final` to prevent subclasses from overriding the `doit` method. This is because the `doit` method is designed to recursively call itself, and overriding this method in subclasses could break the recursion and lead to unexpected behavior.

## Backwards Compatibility

Adding the final qualifier to existing classes may break backward compatibility for users who were relying on subclassing those classes. However, this change can be introduced gradually, and the benefits of improved code design and maintainability outweigh the potential compatibility concerns.

## Detailed Description

The implementation will involve the following steps:

1. Identify classes within SymPy that are suitable candidates for the final qualifier.
2. Add the final keyword to the class definitions of the identified classes.
3. Update the documentation to highlight the classes that are now marked as final.
4. Classes that are candidates for the final qualifier are those that are not designed to be subclassed and are crucial to the core functionality of SymPy.

## Alternatives

An alternative approach would be to rely solely on documentation and conventions to discourage subclassing and overriding, without using the final qualifier. However, relying solely on documentation can lead to misunderstandings and unintended subclassing and overriding.

## Discussion

- [Link to Mailing List Discussion]

## References

- [PEP 591](https://peps.python.org/pep-0591/)

## Copyright

This document has been placed in the public domain.