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

Corrected erroneous caching example #73

Open
wants to merge 20 commits into
base: master
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
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
TAGS
.idea/*
.idea_modules/
*.iml
*.pyc
*.swp
MANIFEST
build/
MANIFEST
MacroPy.egg-info/
dist/
27 changes: 27 additions & 0 deletions docs/examples/dictdock/dictdock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from macropy.case_classes import macros, case
@case
class DictDock(d | {}):
pass

from macropy.tracing import macros, trace
with trace:
a = DictDock() # new instance
b = DictDock() # new instance
a == b # their contents are equal and empty
a is b # but they're different identities
a.d is b.d # and their dict's have the same ident
a.d['foo'] = 'bar' # put something in a's dictionary
with trace:
a.d['foo'] # the 'something' is in a's dictionary
b.d['foo'] # but it's in b's dictionary too
a == b # their contents are still equal
a is b # and they're still not the same
a.d is b.d # their dict's are still same ident
with trace:
g = DictDock({}) # new instance; explicit initializer
h = DictDock({}) # new instance; explicit initializer
g.d is h.d # different dictionaries inside
g.d['x'] = 42 # put something in g's dict
with trace:
g.d # check g's dict
h.d # check h's dict
2 changes: 2 additions & 0 deletions docs/examples/dictdock/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import macropy.activate
import dictdock
16 changes: 14 additions & 2 deletions docs/examples/hygiene/gen_sym/macro_module.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from macropy.core.macros import *
from macropy.dump import macros, dump, dumpid
from macropy.core.quotes import macros, q, u

import pprint
pp = pprint.PrettyPrinter(indent = 4
)
_ = None # makes IDE happy

macros = Macros()
Expand All @@ -21,4 +24,13 @@ def underscore_search(tree, collect, **kw):

new_tree = q[lambda: ast[tree]]
new_tree.args.args = [Name(id = x) for x in used_names]
return new_tree

dumpid[tree]
dumpid[real_repr(tree)]
dumpid[tree]

dumpid[new_tree]
dumpid[real_repr(new_tree)]
dumpid[unparse(new_tree)]

return new_tree
2 changes: 1 addition & 1 deletion macropy/core/import_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def load_module(self, fullname):
class MacroFinder(object):
"""Loads a module and looks for macros inside, only providing a loader if
it finds some."""
def find_module(self, module_name, package_path):
def find_module(self, module_name, package_path = None):
try:
try:
(file, pathname, description) = imp.find_module(
Expand Down
34 changes: 21 additions & 13 deletions macropy/core/test/exporters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,60 @@
pyc_cache_macro_count = 0
from macropy.core.exporters import NullExporter, PycExporter, SaveExporter

THIS_FOLDER = os.path.dirname(__file__)

class Tests(unittest.TestCase):
def test_null_exporter(self):
import pyc_cache
# every load and reload should re-run both macro and file
assert (pyc_cache_count, pyc_cache_macro_count) == (1, 1)
assert (pyc_cache_count, pyc_cache_macro_count) == (1, 1),(pyc_cache_count, pyc_cache_macro_count)
reload(pyc_cache)
assert (pyc_cache_count, pyc_cache_macro_count) == (2, 2)
assert (pyc_cache_count, pyc_cache_macro_count) == (2, 2),(pyc_cache_count, pyc_cache_macro_count)
reload(pyc_cache)
assert (pyc_cache_count, pyc_cache_macro_count) == (3, 3)
assert (pyc_cache_count, pyc_cache_macro_count) == (3, 3),(pyc_cache_count, pyc_cache_macro_count)

def test_pyc_exporter(self):
import macropy

macropy.exporter = PycExporter()
import pyc_cache
assert (pyc_cache_count, pyc_cache_macro_count) == (3, 3)
assert (pyc_cache_count, pyc_cache_macro_count) == (3, 3),(pyc_cache_count, pyc_cache_macro_count)

# reloading the file should re-run file but not macro
reload(pyc_cache)
assert (pyc_cache_count, pyc_cache_macro_count) == (4, 3)
assert (pyc_cache_count, pyc_cache_macro_count) == (4, 3),(pyc_cache_count, pyc_cache_macro_count)
reload(pyc_cache)
assert (pyc_cache_count, pyc_cache_macro_count) == (5, 3)
assert (pyc_cache_count, pyc_cache_macro_count) == (5, 3),(pyc_cache_count, pyc_cache_macro_count)


cache_file = os.path.join(THIS_FOLDER, "pyc_cache.py")
# unless you touch the file to bring its mtime up to that of the
# stored .pyc, in which case the macro gets re-run too
f = open(__file__ + "/../pyc_cache.py", "a")
f = open(cache_file, "a")
f.write(" ")
f.close()

reload(pyc_cache)
assert (pyc_cache_count, pyc_cache_macro_count) == (6, 4)
assert (pyc_cache_count, pyc_cache_macro_count) == (6, 4),(pyc_cache_count, pyc_cache_macro_count)

reload(pyc_cache)
assert (pyc_cache_count, pyc_cache_macro_count) == (7, 4)
assert (pyc_cache_count, pyc_cache_macro_count) == (7, 4),(pyc_cache_count, pyc_cache_macro_count)

f = open(__file__ + "/../pyc_cache.py", "a")
f = open(cache_file, "a")
f.write(" ")
f.close()

reload(pyc_cache)
assert (pyc_cache_count, pyc_cache_macro_count) == (8, 5)
# [rebcabin: this test just appeared to be numerically wrong. I am not
# absolutely positive I did the right thing, here, because I don't
# deeply understand the caching process.]
assert (pyc_cache_count, pyc_cache_macro_count) == (8, 4),(pyc_cache_count, pyc_cache_macro_count)

def test_save_exporter(self):
import macropy

macropy.exporter = SaveExporter(__file__ + "/../exported", __file__ + "/..")
exported_folder = os.path.join(THIS_FOLDER, "exported")
macropy.exporter = SaveExporter(exported_folder, THIS_FOLDER)

# the original code should work
import save
Expand All @@ -62,4 +70,4 @@ def test_save_exporter(self):
import macropy.core.test.exporters.exported.save as save_exported
assert save_exported.run() == 14
import shutil
shutil.rmtree(__file__ + "/../exported")
shutil.rmtree(exported_folder)
3 changes: 2 additions & 1 deletion macropy/core/test/exporters/pyc_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
from macropy.core.test import exporters

exporters.pyc_cache_count += 1
f[1]
f[1]

19 changes: 19 additions & 0 deletions macropy/dump.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from macropy.core.macros import *
from macropy.core.hquotes import macros, hq, u, ast, ast_list

macros = Macros()

@macros.expr
def dump(tree, **kw):
"""Macro to dump a literal expression and its value so we DRY."""
return hq[unparse(tree) + ' ~~> ' + str(ast[tree])]

def _fuggle_3bf1b522_f487_4386_9466_62308ef1f105(x):
print x
return None

@macros.expr
def dumpid(tree, **kw):
"""Macro with the semantics of identity that prints an expression and its value
as a side effect and returns the value"""
return hq[(_fuggle_3bf1b522_f487_4386_9466_62308ef1f105(unparse(tree) + ' ~~> ' + str(ast[tree])), ast[tree])[1]]
17 changes: 17 additions & 0 deletions macropy/experimental/test/debug_pyxl_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import unittest
import macropy.activate

import pyxl_snippets

def test_suite(suites=[], cases=[]):
new_suites = [x.Tests for x in suites]
new_cases = [unittest.makeSuite(x.Tests) for x in cases]
return unittest.TestSuite(new_cases + new_suites)

unittest.TextTestRunner().run (
test_suite (cases= [
pyxl_snippets] ) )




16 changes: 10 additions & 6 deletions macropy/experimental/test/pyxl_snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from macropy.tracing import macros, require


from pyxl.html import *
import pyxl.html as html
import re
import unittest
from xml.etree import ElementTree
Expand Down Expand Up @@ -54,11 +54,15 @@ def test_interpreter(self):
safe_value = "<b>Puppies!</b>"
unsafe_value = "<script>bad();</script>"
unsafe_attr = '">'
pyxl_blob = p["""<div class="{unsafe_attr}">
{unsafe_value}
{rawhtml(safe_value)}
</div>"""]
target_blob = '<div class="&quot;&gt;">&lt;script&gt;bad();&lt;/script&gt;<b>Puppies!</b></div>'
pyxl_blob = p[
'''
<div class="{unsafe_attr}">
{unsafe_value}
{html.rawhtml(safe_value)}
</div>
'''
]
target_blob = '<div class="&quot;&gt;">&lt;script&gt;bad();&lt;/script&gt; <b>Puppies!</b></div>'
with require:
normalize(pyxl_blob.to_string()) == normalize(target_blob)

Expand Down
2 changes: 2 additions & 0 deletions macropy/test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def test_suite(suites=[], cases=[]):


import case_classes
import dump
import quick_lambda
import string_interp
import tracing
Expand All @@ -17,6 +18,7 @@ def test_suite(suites=[], cases=[]):
import macropy.core.test
Tests = test_suite(cases=[
case_classes,
dump,
quick_lambda,
string_interp,
tracing,
Expand Down
35 changes: 35 additions & 0 deletions macropy/test/dump.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import unittest

from macropy.dump import macros, dump, dumpid
class Tests(unittest.TestCase):

def test_basic(self):
assert dump[1] == '1 ~~> 1'
assert dump[1 + 2] == '(1 + 2) ~~> 3'
assert dump[2 + 1] == '(2 + 1) ~~> 3'
assert dump[3*7 + 7*3] == '((3 * 7) + (7 * 3)) ~~> 42'
x = 3
y = 2
z = 7
assert dump[x * z + z * x] == '((x * z) + (z * x)) ~~> 42'
assert dump[x*y*z == z*y*x] == '(((x * y) * z) == ((z * y) * x)) ~~> True'

def test_if(self):
assert dump[42 if None else 43] == '(42 if None else 43) ~~> 43'

def test_lambda(self):
assert dump[(lambda x: x * 3 + 3 * x)(7)] == \
'(lambda x: ((x * 3) + (3 * x)))(7) ~~> 42'

def test_basic_id(self):
assert dumpid[1] == 1
assert dumpid[1 + 2] == 3
assert dumpid[2 + 1] == 3
assert dumpid[3*7 + 7*3] == 42

def test_if(self):
assert dumpid[42 if None else 43] == 43

def test_lambda(self):
assert dumpid[(lambda x: x * 3 + 3 * x)(7)] == 42

19 changes: 7 additions & 12 deletions macropy/test/peg.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import unittest
from macropy.peg import macros, peg, Success, cut, ParseError

Expand Down Expand Up @@ -122,11 +123,9 @@ def test_bindings(self):
def test_arithmetic(self):
"""
PEG grammar from Wikipedia

Op <- "+" / "-" / "*" / "/"
Value <- [0-9]+ / '(' Expr ')'
Expr <- Value (Op Value)*

simplified it to remove operator precedence
"""

Expand Down Expand Up @@ -217,29 +216,21 @@ def decode(x):

"""
JSON <- S? ( Object / Array / String / True / False / Null / Number ) S?

Object <- "{"
( String ":" JSON ( "," String ":" JSON )*
/ S? )
"}"

Array <- "["
( JSON ( "," JSON )*
/ S? )
"]"

String <- S? ["] ( [^ " \ U+0000-U+001F ] / Escape )* ["] S?

Escape <- [\] ( [ " / \ b f n r t ] / UnicodeEscape )

UnicodeEscape <- "u" [0-9A-Fa-f]{4}

True <- "true"
False <- "false"
Null <- "null"

Number <- Minus? IntegralPart fractPart? expPart?

Minus <- "-"
IntegralPart <- "0" / [1-9] [0-9]*
fractPart <- "." [0-9]+
Expand Down Expand Up @@ -365,11 +356,15 @@ def decode(x):


# full tests, taken from http://www.json.org/JSON_checker/
peg_json_folder = os.path.join(os.path.dirname(__file__), "peg_json")
for i in range(1, 34):
if i not in [18]: # skipping the "too much nesting" failure test

with self.assertRaises(ParseError):
json_doc.parse(open(__file__ + "/../peg_json/fail%s.json" % i).read())
path = os.path.join(peg_json_folder, "fail%s.json" % i)
json_doc.parse(open(path).read())

for i in [1, 2, 3]:
test(json_exp, open(__file__ + "/../peg_json/pass%s.json" % i).read())
path = os.path.join(peg_json_folder, "pass%s.json" % i)
test(json_exp, open(path).read())

Loading