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

[Fix Issue54]: Trouble parsing unassigned expressions #55

Merged
merged 5 commits into from
Mar 27, 2024
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
14 changes: 7 additions & 7 deletions representer/normalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
Assign,
AsyncFunctionDef,
Attribute,
BinOp,
BoolOp,
Call,
ClassDef,
Compare,
Expand All @@ -22,6 +24,7 @@
GeneratorExp,
Global,
If,
Lambda,
ListComp,
Load,
Module,
Expand All @@ -31,7 +34,9 @@
SetComp,
Str,
Store,
UnaryOp,
Yield,
YieldFrom,
alias,
arg,
get_docstring,
Expand Down Expand Up @@ -311,13 +316,8 @@ def visit_Expr(self, node: Expr) -> Optional[Expr]:
if node.value.func.id == 'print':
return None

# Pass through generator code.
if isinstance(node.value, Yield):
return node


# Eliminate previously registered docstrings
if not isinstance(node.value, Call):
if isinstance(node.value, Constant) and not isinstance(node.value, Call):
# eliminate registered docstrings
if utils.md5sum(node.value.value) in self._docstring_cache:
return None

Expand Down
18 changes: 9 additions & 9 deletions test/concept-plane-tickets/representation.out
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ placeholder_0 = ["A", "B", "C", "D"]

def placeholder_1(placeholder_2):
for placeholder_3 in range(placeholder_2):
yield SEATS_IN_ROW[seat % 4]
yield placeholder_0[placeholder_3 % 4]


def placeholder_4(placeholder_2):
Expand All @@ -15,7 +15,7 @@ def placeholder_4(placeholder_2):
for placeholder_3 in range(placeholder_2):
placeholder_6 = math.ceil((placeholder_3 + 1) / 4)
if placeholder_6 != 13:
yield f"{str(row_number)}{next(letters)}"
yield f"{str(placeholder_6)}{next(placeholder_5)}"


def placeholder_7(placeholder_8):
Expand All @@ -31,7 +31,7 @@ def placeholder_7(placeholder_8):
def placeholder_12(placeholder_13, placeholder_14):
for placeholder_3 in placeholder_13:
placeholder_15 = f"{placeholder_3}{placeholder_14}"
yield (base_string + "0" * (12 - len(base_string)))
yield (placeholder_15 + "0" * (12 - len(placeholder_15)))

## END NORMALIZED CODE ##

Expand Down Expand Up @@ -1023,15 +1023,15 @@ Module(
Yield(
Subscript(
Name(
'SEATS_IN_ROW',
'placeholder_0',
Load(),
lineno=22,
col_offset=14,
end_lineno=22,
end_col_offset=26),
BinOp(
Name(
'seat',
'placeholder_3',
Load(),
lineno=22,
col_offset=27,
Expand Down Expand Up @@ -1318,7 +1318,7 @@ Module(
end_col_offset=24),
[
Name(
'row_number',
'placeholder_6',
Load(),
lineno=47,
col_offset=25,
Expand All @@ -1345,7 +1345,7 @@ Module(
end_col_offset=42),
[
Name(
'letters',
'placeholder_5',
Load(),
lineno=47,
col_offset=43,
Expand Down Expand Up @@ -1663,7 +1663,7 @@ Module(
Yield(
BinOp(
Name(
'base_string',
'placeholder_15',
Load(),
lineno=80,
col_offset=14,
Expand Down Expand Up @@ -1696,7 +1696,7 @@ Module(
end_col_offset=43),
[
Name(
'base_string',
'placeholder_15',
Load(),
lineno=80,
col_offset=44,
Expand Down
2 changes: 1 addition & 1 deletion test/concept-plane-tickets/representation.txt

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions test/example-expression-normalization/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"authors": [
"bethanyg","brocla"
],
"files": {
"solution": [
"example_expression_normalization.py"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
"""Hanging Module docstring.

This is to make sure that the Expression changes don't munge things"""


import unittest
import pytest
from dataclass import dataclass
from Enum import Flag


# Examples of "Hanging Expressions (expressions not assigned to a name)"
# These have been barfing in the representer, due to bad refrences when
# checking the cache.

# hanging uninitialized dataclass
@dataclass
class Point:
"""Docstring to test removal."""
x: int = 0
y: int = 0


# Hanging try/except
try:
1/0
except:
pass


# Random addition
5+6


# Hanging print() (should get removed)
print(5+6)


# Various hanging comprehensions and genexps
(item for item in range(8))
[item for item in range(16)]
{item for item in "a b c d e f g h i".split()}
{key:value for key, value in ((1, "a"),(2, "b"),(3, "c"),(5, "e"))}

# Hanging and not hanging lambdas
lambda : {key:value for key, value in ((1, "a"),(2, "b"),(3, "c"),(5, "e"))}
test_assign_name = lambda : {item for item in "a b c d e f g h i".split()}


# hanging "constants"
-a
THIS_IS_A_CONSTANT = "It would be stupid if this exploded."

"""Random Hanging String"""


# hanging Enum
class Allergene(Flag):
eggs = auto()
peanuts = auto()
shellfish = auto()
strawberries = auto()
tomatoes = auto()
chocolate = auto()
pollen = auto()
cats = auto()

# The below is a hanging try/except from Guido's Gorgeous Lasagna exercise.

# For this first exercise, it is really important to be clear about how we are importing names for tests.
# To that end, we are putting a try/catch around imports and throwing specific messages to help students
# decode that they need to create and title their constants and functions in a specific way.
try:
from lasagna import (EXPECTED_BAKE_TIME,
bake_time_remaining,
preparation_time_in_minutes,
elapsed_time_in_minutes)

# Here, we are separating the constant import errors from the function name import errors
except ImportError as import_fail:
message = import_fail.args[0].split('(', maxsplit=1)
item_name = import_fail.args[0].split()[3]

if 'EXPECTED_BAKE_TIME' in item_name:
# pylint: disable=raise-missing-from
raise ImportError(f'\n\nMISSING CONSTANT --> \nWe can not find or import the constant {item_name} in your'
" 'lasagna.py' file.\nDid you misname or forget to define it?") from None
else:
item_name = item_name[:-1] + "()'"
# pylint: disable=raise-missing-from
raise ImportError("\n\nMISSING FUNCTION --> In your 'lasagna.py' file, we can not find or import the"
f' function named {item_name}. \nDid you misname or forget to define it?') from None


# The below examples overlap with other tests, but are here to show that
# the docstring removals don't alter other expression-type code.


def slices(series, length):
"""
Given a string of digits, output all the contiguous substrings of length `n`,
in that string, in the order that they appear.
"""
return [
sub_str
for i, _ in enumerate(series)
if len(sub_str := series[i : i + length]) == length
]


# yield from and yield examples
from typing import Iterable
def flatten(iterable):
def go(it):
for e in it:
if isinstance(e, Iterable) and not isinstance(e, str):
yield from go(e)
else:
yield e
return [e for e in go(iterable) if e is not None]



def check_height(grid):
"""check that row count is a multiple of 4"""
if (height := len(grid)) % 3:
raise ValueError("grid rows not a multiple of 4")
return height


def nswe_points(self, point):
"""return a set of four adjacent points"""
nswe_offsets = set([(1, 0), (-1, 0), (0, -1), (0, 1)])
return {
neighbor
for offset in nswe_offsets
if self.on_the_board(neighbor := point + offset)
}


def first_item_greater_than_N(iterable, N):
if any((item := x) > N for x in iterable):
return item
return None


def generate_codes(seat_numbers, flight_id):
"""Generate codes for a ticket.

:param seat_numbers: list[str] - list of seat numbers.
:param flight_id: str - string containing the flight identifier.
:return: generator - generator that yields 12 character long ticket codes.

"""
return (
base.ljust(12, "0") for seat in seat_numbers if (base := f"{seat}{flight_id}")
)
50 changes: 50 additions & 0 deletions test/example-expression-normalization/mapping.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"placeholder_0": "Point",
"placeholder_1": "x",
"placeholder_2": "y",
"placeholder_3": "item",
"placeholder_4": "key",
"placeholder_5": "value",
"placeholder_6": "test_assign_name",
"placeholder_7": "THIS_IS_A_CONSTANT",
"placeholder_8": "Allergene",
"placeholder_9": "eggs",
"placeholder_10": "peanuts",
"placeholder_11": "shellfish",
"placeholder_12": "strawberries",
"placeholder_13": "tomatoes",
"placeholder_14": "chocolate",
"placeholder_15": "pollen",
"placeholder_16": "cats",
"placeholder_17": "import_fail",
"placeholder_18": "message",
"placeholder_19": "maxsplit",
"placeholder_20": "item_name",
"placeholder_21": "slices",
"placeholder_22": "series",
"placeholder_23": "length",
"placeholder_24": "i",
"placeholder_25": "_",
"placeholder_26": "sub_str",
"placeholder_27": "flatten",
"placeholder_28": "iterable",
"placeholder_29": "go",
"placeholder_30": "it",
"placeholder_31": "e",
"placeholder_32": "check_height",
"placeholder_33": "grid",
"placeholder_34": "height",
"placeholder_35": "nswe_points",
"placeholder_36": "point",
"placeholder_37": "nswe_offsets",
"placeholder_38": "offset",
"placeholder_39": "neighbor",
"placeholder_40": "first_item_greater_than_N",
"placeholder_41": "N",
"placeholder_42": "placeholder_3",
"placeholder_43": "generate_codes",
"placeholder_44": "seat_numbers",
"placeholder_45": "flight_id",
"placeholder_46": "seat",
"placeholder_47": "base"
}
3 changes: 3 additions & 0 deletions test/example-expression-normalization/representation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"version": 2
}
Loading
Loading