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

Python frontend: Class definition and instantiation #1552

Merged
merged 21 commits into from Dec 23, 2023

Conversation

brcfarias
Copy link
Collaborator

@brcfarias brcfarias commented Dec 20, 2023

This pull request adds support for class definition and instantiation.
Some relevant details:

  • The init() method is treated as class constructor.
  • In constructor calls like obj1 = MyClass(..), obj1 is passed as the first argument to the constructor.
  • In Python, "Variables defined in the class definition are class attributes; they are shared by instances. Instance attributes can be set in a method with self.name = value. Both class and instance attributes are accessible through the notation “self.name”, and an instance attribute hides a class attribute with the same name when accessed in this way."(https://docs.python.org/3/reference/compound_stmts.html#class).
  • This pull request specifically addresses instance attributes. When an attribute is referred by "self" it is added as a field to the corresponding self type. Class attributes will be addressed in a future (perhaps the next) PR.
  • The current implementation does not yet consider default inheritance from "object" class. This feature will also be addressed in a subsequent update.

@@ -234,6 +234,9 @@ void clang_c_adjust::adjust_side_effect(side_effect_exprt &expr)
else if (statement == "gcc_conditional_expression")
{
}
else if (statement == "nondet")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have this statement?

Copy link
Collaborator Author

@brcfarias brcfarias Dec 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add some comments here?

@@ -125,8 +134,17 @@ class python_annotation

// lhs
auto target = element["targets"][0];
int col_offset = target["col_offset"].template get<int>() +
target["id"].template get<std::string>().size() + 1;
std::string id;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add some comments here?

@@ -156,6 +174,26 @@ class python_annotation
element["value"]["end_col_offset"] =
element["value"]["end_col_offset"].template get<int>() + type.size() +
1;

if (element["value"].contains("args"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some comments here?

{
std::string symbol_id = "py:" + python_filename;
if (!current_class_name.empty())
symbol_id += "@C@" + current_class_name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The + operator is usually okay for small string operations. However, it might be more efficiently done using std::stringstream or std::string::append to avoid unnecessary copying.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed to stringstream. Thanks.

if (it.first == "identifier")
obj_type_name = it.second.id_string();
}
assert(!obj_type_name.empty());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we really use assert statements here? What happens with the release mode when we disable these assertions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In release we would have a crash when dereferecing class_symbol at https://github.com/brcfarias/esbmc/blob/69112185c12d40be1eed5d87ea57c4eb6e9e23ac/src/python-frontend/python_converter.cpp#L502C1-L503C1.

I will remove the asserts, check if class_symbol is valid before dereferencing, and call abort() if so.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent! Thanks, @brcfarias.

Copy link
Contributor

@lucasccordeiro lucasccordeiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing my comments, @brcfarias.

Copy link
Member

@fbrausse fbrausse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general looks like a good approach to me.

Since supporting the full dynamic nature of the language is probably out of scope, I'd suggest to start documenting the particular Python dialect supported by this frontend. Some things like the following reflect existing practice, but are not required by the language:

  • name self isn't fixed (could also be me or any other valid identifier)
  • restriction about int values we talked about before
  • computed instance attibutes not supported (e.g. non-literal access via get/setattr())
  • variable declarations need type annotations

@lucasccordeiro lucasccordeiro merged commit 7c6d7d6 into esbmc:master Dec 23, 2023
7 checks passed
@lucasccordeiro
Copy link
Contributor

Thanks for submitting this PR, @brcfarias.

Can you please submit another PR that addresses @fbrausse's suggestion about the documentation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants