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

Make type annotation optional for self argument of bound methods #1626

Merged
merged 8 commits into from
Nov 22, 2023
Merged
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- #1571 : Add support for the function `tuple`.
- #1493 : Add preliminary support for importing classes.
- \[INTERNALS\] Add `class_type` attribute to `TypedAstNode`.
- #1578 : Allow classes to avoid type annotations for the self argument of a method.

### Fixed

Expand Down
12 changes: 6 additions & 6 deletions docs/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,23 @@ import numpy as np
from pyccel.decorators import inline

class MyClass:
def __init__(self : 'MyClass', param1 : 'int', param2 : 'int'):
def __init__(self, param1 : 'int', param2 : 'int'):
self.param1 = param1
self.param2 = np.ones(param2)
print("MyClass Object created!")

@inline
def get_param(self : 'MyClass'):
def get_param(self):
print(self.param1, self.param2)

class MyClass1:
def __init__(self : 'MyClass1'):
def __init__(self):
print("MyClass1 Object created!")

def Method1(self : 'MyClass1', param1 : 'MyClass'):
def Method1(self, param1 : MyClass):
self.param = param1

def Method2(self : 'MyClass1'):
def Method2(self):
return MyClass(2, 4)

if __name__ == '__main__':
Expand Down Expand Up @@ -192,4 +192,4 @@ MyClass Object created!

## Limitations

It's important to note that Pyccel does not support class inheritance, properties, magic methods or class variables. For our first implementation, the focus of Pyccel is primarily on core class functionality and memory management.
It's important to note that Pyccel does not support class inheritance, properties, magic methods or static class variables. For our first implementation, the focus of Pyccel is primarily on core class functionality and memory management.
13 changes: 13 additions & 0 deletions pyccel/parser/syntactic.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ def _visit_AnnAssign(self, stmt):
return Assign(annotated_lhs, rhs)

def _visit_arguments(self, stmt):
is_class_method = len(self._context) > 2 and isinstance(self._context[-3], ast.ClassDef)

if stmt.vararg or stmt.kwarg:
errors.report(VARARGS, symbol = stmt,
Expand All @@ -489,6 +490,18 @@ def _visit_arguments(self, stmt):
new_arg.set_current_ast(a)
arguments.append(new_arg)

headers = self.scope.find(self._context[-2].name, 'headers') \
if isinstance(self._context[-2], ast.FunctionDef) else None

if is_class_method and not headers:
expected_self_arg = arguments[0]
if expected_self_arg.annotation is None:
class_name = self._context[-3].name
annotation = self._treat_type_annotation(class_name, PyccelSymbol(class_name))
arguments[0] = FunctionDefArgument(AnnotatedPyccelSymbol(expected_self_arg.name, annotation),
annotation=annotation,
value = expected_self_arg.value)

if stmt.kwonlyargs:
for a,d in zip(stmt.kwonlyargs,stmt.kw_defaults):
annotation=self._treat_type_annotation(a, self._visit(a.annotation))
Expand Down
2 changes: 1 addition & 1 deletion tests/pyccel/scripts/classes/classes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# pylint: disable=missing-class-docstring, missing-function-docstring, missing-module-docstring

class Point(object):
def __init__(self : 'Point', x : float, y : float):
def __init__(self, x : float, y : float):
self.x = x
self.y = y

Expand Down
12 changes: 6 additions & 6 deletions tests/pyccel/scripts/classes/classes_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@
# coding: utf-8

class Point:
def __init__(self : 'Point', x : float, y : float):
def __init__(self, x : float, y : float):
self.x = x
self.X = y

def set_coordinates(self : 'Point', x : float, y : float):
def set_coordinates(self, x : float, y : float):
self.x = x
self.X = y

def get_coordinates(self : 'Point'):
def get_coordinates(self):
return self.x, self.X

class Point1:
def __init__(self : 'Point1', x : float):
def __init__(self, x : float):
self.x = x

class Point2:
def __init__(self : 'Point2', y : float):
def __init__(self, y : float):
self.y = y

def test_func(self : 'Point2'):
def test_func(self):
p = Point1(self.y)
print(p.x)

Expand Down
Loading