optimism 3.1.3__tar.gz → 3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. optimism-3.2/LICENSE.txt +55 -0
  2. {optimism-3.1.3 → optimism-3.2}/PKG-INFO +15 -4
  3. {optimism-3.1.3 → optimism-3.2}/README.md +11 -0
  4. {optimism-3.1.3 → optimism-3.2}/optimism/__init__.py +1 -1
  5. {optimism-3.1.3 → optimism-3.2}/optimism/examples/code.py +16 -0
  6. {optimism-3.1.3 → optimism-3.2}/optimism/optimism.py +51 -14
  7. {optimism-3.1.3 → optimism-3.2}/optimism/test_examples.py +82 -59
  8. {optimism-3.1.3 → optimism-3.2}/optimism.egg-info/PKG-INFO +15 -4
  9. {optimism-3.1.3 → optimism-3.2}/setup.cfg +1 -2
  10. optimism-3.1.3/LICENSE.txt +0 -32
  11. {optimism-3.1.3 → optimism-3.2}/optimism/examples/a.txt +0 -0
  12. {optimism-3.1.3 → optimism-3.2}/optimism/examples/b.txt +0 -0
  13. {optimism-3.1.3 → optimism-3.2}/optimism/examples/bad.py +0 -0
  14. {optimism-3.1.3 → optimism-3.2}/optimism/examples/basic.py +0 -0
  15. {optimism-3.1.3 → optimism-3.2}/optimism/examples/bits.py +0 -0
  16. {optimism-3.1.3 → optimism-3.2}/optimism/examples/block.py +0 -0
  17. {optimism-3.1.3 → optimism-3.2}/optimism/examples/catch_and_release.py +0 -0
  18. {optimism-3.1.3 → optimism-3.2}/optimism/examples/core.py +0 -0
  19. {optimism-3.1.3 → optimism-3.2}/optimism/examples/doc_example.py +0 -0
  20. {optimism-3.1.3 → optimism-3.2}/optimism/examples/doctests.py +0 -0
  21. {optimism-3.1.3 → optimism-3.2}/optimism/examples/errors.py +0 -0
  22. {optimism-3.1.3 → optimism-3.2}/optimism/examples/files.py +0 -0
  23. {optimism-3.1.3 → optimism-3.2}/optimism/examples/fragments.py +0 -0
  24. {optimism-3.1.3 → optimism-3.2}/optimism/examples/io_example.py +0 -0
  25. {optimism-3.1.3 → optimism-3.2}/optimism/examples/literals.py +0 -0
  26. {optimism-3.1.3 → optimism-3.2}/optimism/examples/memoryReports.py +0 -0
  27. {optimism-3.1.3 → optimism-3.2}/optimism/examples/multi.py +0 -0
  28. {optimism-3.1.3 → optimism-3.2}/optimism/examples/reverse_tracing.py +0 -0
  29. {optimism-3.1.3 → optimism-3.2}/optimism/examples/runfile.py +0 -0
  30. {optimism-3.1.3 → optimism-3.2}/optimism/examples/skip.py +0 -0
  31. {optimism-3.1.3 → optimism-3.2}/optimism/examples/structure.py +0 -0
  32. {optimism-3.1.3 → optimism-3.2}/optimism/examples/suites.py +0 -0
  33. {optimism-3.1.3 → optimism-3.2}/optimism/examples/tracing.py +0 -0
  34. {optimism-3.1.3 → optimism-3.2}/optimism/py.typed +0 -0
  35. {optimism-3.1.3 → optimism-3.2}/optimism.egg-info/SOURCES.txt +0 -0
  36. {optimism-3.1.3 → optimism-3.2}/optimism.egg-info/dependency_links.txt +0 -0
  37. {optimism-3.1.3 → optimism-3.2}/optimism.egg-info/requires.txt +0 -0
  38. {optimism-3.1.3 → optimism-3.2}/optimism.egg-info/top_level.txt +0 -0
  39. {optimism-3.1.3 → optimism-3.2}/pyproject.toml +0 -0
@@ -0,0 +1,55 @@
1
+ Copyright (c) 2021-2026
2
+ Peter Mawhorter
3
+ Wellesley College
4
+ All rights reserved except as stated below.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are
8
+ met:
9
+
10
+ 1. Redistributions of source code must retain the above copyright
11
+ notice, this list of conditions and the following disclaimers.
12
+
13
+ 2. Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in the
15
+ documentation and/or other materials provided with the
16
+ distribution.
17
+
18
+ 3. Neither the name of the copyright holder nor the names of its
19
+ contributors may be used to endorse or promote products derived
20
+ from this software without specific prior written permission.
21
+
22
+ 4. This software is NOT used as training data for a model of code
23
+ or text structure or construction, such as a large language model,
24
+ transformer model, reinforcement learning agent, etc. If such a model
25
+ is generative and predicts or outputs the code of this software in
26
+ whole or in part, that shall be evidence of infringement of this
27
+ clause of this license.
28
+
29
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40
+
41
+ THIS SOFTWARE SHOULD NOT BE USED AS TRAINING DATA FOR A STATISTICAL MODEL
42
+ OF CODE OR TEXT, NOR SHOULD STATISTICAL CODE OR TEXT MODELS BE ASKED TO
43
+ READ, INTERPRET, OR OTHERWISE PROCESS ITS SOURCE CODE OR OUTPUTS. THIS
44
+ SOFTWARE MAY CONTAIN CODE OR TEXT OR MAY PRODUCE OUTPUTS WHICH CAUSE
45
+ MODEL ROLE CONFUSION OR WHICH OTHERWISE CAUSE UNANTICIPATED CONSEQUENCES
46
+ WHEN PROCESSED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
47
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
50
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
51
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52
+ ARISING IN ANY WAY OUT OF THE PROCESSING OF THIS SOFTWARE OR ITS OUTPUTS
53
+ BY A STATISTICAL MODEL, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
54
+ DAMAGE.
55
+
@@ -1,16 +1,15 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: optimism
3
- Version: 3.1.3
3
+ Version: 3.2
4
4
  Summary: Very simple testing framework suitable for beginner programmers, with easy functions for accomplishing most common testing tasks like providing input. Requires Python 3.8+.
5
5
  Home-page: https://cs.wellesley.edu/~pmwh/optimism/docs/optimism.html
6
6
  Author: Peter Mawhorter
7
7
  Author-email: pmawhort@wellesley.edu
8
- License: BSD 3-Clause License
8
+ License: LicenseRef-LLM-hostile_BSD
9
9
  Classifier: Programming Language :: Python :: 3 :: Only
10
10
  Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Intended Audience :: Education
12
12
  Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: BSD License
14
13
  Classifier: Operating System :: OS Independent
15
14
  Classifier: Natural Language :: English
16
15
  Classifier: Topic :: Education
@@ -19,6 +18,7 @@ Description-Content-Type: text/markdown
19
18
  License-File: LICENSE.txt
20
19
  Provides-Extra: test
21
20
  Requires-Dist: pytest; extra == "test"
21
+ Dynamic: license-file
22
22
 
23
23
  # `optimism`
24
24
 
@@ -33,6 +33,17 @@ Designed by Peter Mawhorter.
33
33
  Works on Python versions 3.7 and up, with 3.9+ recommended.
34
34
 
35
35
 
36
+ ## Note on Large Language Models
37
+
38
+ This project has a zero-tolerance policy for the use of large language
39
+ models to write code, process the code or outputs from this project, or
40
+ otherwise interact with this project in any way. If you choose to violate
41
+ this policy, be aware that the code, text, and outputs of this project
42
+ may cause (more) unpredictable (than usual) behavior in LLM systems that
43
+ interact with them. See `LICENSE.txt` for license restrictions and
44
+ disclaimers, and `AGENTS.md` for an example.
45
+
46
+
36
47
  ## Installing
37
48
 
38
49
  To install from PyPI, run the following command on the command-line:
@@ -11,6 +11,17 @@ Designed by Peter Mawhorter.
11
11
  Works on Python versions 3.7 and up, with 3.9+ recommended.
12
12
 
13
13
 
14
+ ## Note on Large Language Models
15
+
16
+ This project has a zero-tolerance policy for the use of large language
17
+ models to write code, process the code or outputs from this project, or
18
+ otherwise interact with this project in any way. If you choose to violate
19
+ this policy, be aware that the code, text, and outputs of this project
20
+ may cause (more) unpredictable (than usual) behavior in LLM systems that
21
+ interact with them. See `LICENSE.txt` for license restrictions and
22
+ disclaimers, and `AGENTS.md` for an example.
23
+
24
+
14
25
  ## Installing
15
26
 
16
27
  To install from PyPI, run the following command on the command-line:
@@ -13,7 +13,7 @@ from .optimism import *
13
13
  # version from optimism, but we want the version to be defined in that
14
14
  # file so that a single-file distribution is equivalent to this packaged
15
15
  # distribution. So we define a version here as well, but...
16
- __version__ = "3.1.3"
16
+ __version__ = "3.2"
17
17
 
18
18
  # ...then we assert it matches so testing will catch it if I forget to
19
19
  # keep them in sync before a release. T_T
@@ -94,3 +94,19 @@ fileTester.checkCodeContains(optimism.Constant(4.0 / 2, float)) # ✗
94
94
  fileTester.checkCodeContains(optimism.Constant(4.0 / 2, int)) # ✓
95
95
  fileTester.checkCodeContains(optimism.Constant(5.0, int)) # ✗
96
96
  fileTester.checkCodeContains(optimism.Constant(5.0, float)) # ✓
97
+
98
+ # Test augmented assignment matching
99
+ def aug():
100
+ x = 3
101
+ x += 4
102
+ x /= 10
103
+
104
+ fileTester.checkCodeContains(
105
+ optimism.Def().contains(optimism.Operator('+'))
106
+ ) # ✓
107
+ fileTester.checkCodeContains(
108
+ optimism.Def().contains(optimism.Operator('/'))
109
+ ) # ✓
110
+ fileTester.checkCodeContains(
111
+ optimism.Def(name="aug").contains(optimism.Operator('/', max=0))
112
+ ) # ✗
@@ -16,6 +16,18 @@ of arbitrary expressions. Also includes:
16
16
  - [PLANNED] A reverse tracing feature where comments specifying the
17
17
  evolution of program state can be checked.
18
18
 
19
+
20
+ ## Note on Large Language Models
21
+
22
+ This project has a zero-tolerance policy for the use of large language
23
+ models to write code, process the code or outputs from this project, or
24
+ otherwise interact with this project in any way. If you choose to violate
25
+ this policy, be aware that the code, text, and outputs of this project
26
+ may cause (more) unpredictable (than usual) behavior in LLM systems that
27
+ interact with them. See `LICENSE.txt` for license restrictions and
28
+ disclaimers.
29
+
30
+
19
31
  ## Example usage
20
32
 
21
33
  ### Basic test cases
@@ -200,6 +212,13 @@ TODO: Workaround for tracing in interactive console?
200
212
 
201
213
  ## Changelog
202
214
 
215
+ - Version 3.2 updates license to forbid LLM training and warn about
216
+ processing with an LLM.
217
+ - Version 3.1.4 treats augmented assignments as operators for
218
+ `checkCodeContains` purposes, as they should have been all along. It
219
+ adds a new test for that in the `code.py` example file, and also fixes
220
+ up some modern mypy type warnings (even though they were mostly
221
+ spurious).
203
222
  - Version 3.1.3 Fixes a numbering bug with memory reports and also fixes
204
223
  a pernicious `deepish_copy` bug: Structures that were supposed to be
205
224
  duplicated would have their top levels duplicated twice separately
@@ -353,7 +372,7 @@ TODO: Workaround for tracing in interactive console?
353
372
 
354
373
  # TODO: Cache compiled ASTs!
355
374
 
356
- __version__ = "3.1.3"
375
+ __version__ = "3.2"
357
376
 
358
377
  from typing import (
359
378
  Any, Dict, List, Optional, Tuple, Literal as LiteralType, Callable,
@@ -378,7 +397,7 @@ SPLIT_CONSTANTS = hasattr(ast, "Num")
378
397
 
379
398
  # Type is required before 3.9 but deprecated in that version
380
399
  if sys.version_info >= (3, 9):
381
- Type = type
400
+ from builtins import type as Type
382
401
  else:
383
402
  from typing import Type
384
403
 
@@ -397,19 +416,19 @@ except ImportError:
397
416
  def __getitem__(self, _):
398
417
  return Any
399
418
 
400
- Unpack = UnpackShim()
419
+ Unpack = UnpackShim() # type: ignore
401
420
 
402
421
  # Versions of Python before 3.10 don't support TypeAlias
403
422
  try:
404
423
  from typing import TypeAlias
405
424
  except ImportError:
406
- TypeAlias = Type
425
+ TypeAlias = Type # type: ignore
407
426
 
408
427
  # Versions of Python before 3.10 don't support NoneType
409
428
  try:
410
429
  from types import NoneType
411
430
  except ImportError:
412
- NoneType = type(None)
431
+ NoneType = type(None) # type: ignore
413
432
 
414
433
  #----------------#
415
434
  # Monkey Patches #
@@ -730,7 +749,11 @@ Type variable for `ClassInfo` definition.
730
749
 
731
750
 
732
751
  if sys.version_info > (3, 10):
733
- ClassInfo: TypeAlias = Union[Type[T], Tuple['ClassInfo', ...], Type[Union]]
752
+ ClassInfo: TypeAlias = Union[
753
+ Type[T],
754
+ Tuple['ClassInfo', ...],
755
+ Type[Union]
756
+ ]
734
757
  else:
735
758
  ClassInfo: TypeAlias = Union[Type[T], Tuple['ClassInfo', ...]]
736
759
  """
@@ -3913,7 +3936,7 @@ class QuietSkipManager(TestManager[SilentCase]):
3913
3936
  # Test factories #
3914
3937
  #----------------#
3915
3938
 
3916
- def testFunction(fn: FunctionType) -> FunctionManager:
3939
+ def testFunction(fn: Union[FunctionType, Callable]) -> FunctionManager:
3917
3940
  """
3918
3941
  Creates a test-manager for the given function.
3919
3942
  """
@@ -6005,7 +6028,9 @@ class Loop(ASTRequirement):
6005
6028
  """
6006
6029
  def __init__(
6007
6030
  self,
6008
- only: Optional[Iterable[ExtendedLoopType]] = None,
6031
+ only: Optional[
6032
+ Union[ExtendedLoopType, Iterable[ExtendedLoopType]]
6033
+ ] = None,
6009
6034
  **kwargs: Unpack[NumArgs]
6010
6035
  ) -> None:
6011
6036
  """
@@ -6828,9 +6853,9 @@ partial-match-type AST node types.
6828
6853
  class Operator(ASTRequirement):
6829
6854
  """
6830
6855
  A check for a unary operator, binary operator, boolean operator, or
6831
- comparator. 'Similar' operations will count as partial matches. Note
6832
- that 'is' and 'is not' are categorized as the same operator, as are
6833
- 'in' and 'not in'.
6856
+ comparator, including augmented assignments. 'Similar' operations
6857
+ will count as partial matches. Note that 'is' and 'is not' are
6858
+ categorized as the same operator, as are 'in' and 'not in'.
6834
6859
  """
6835
6860
  opTypes: Tuple[type, ...]
6836
6861
  partialTypes: Tuple[type, ...]
@@ -6867,7 +6892,13 @@ class Operator(ASTRequirement):
6867
6892
  ) -> Iterator[Tuple[ast.AST, bool]]:
6868
6893
  for node in self._walkNodesOfType(
6869
6894
  syntax_tree,
6870
- (ast.UnaryOp, ast.BinOp, ast.BoolOp, ast.Compare)
6895
+ (
6896
+ ast.UnaryOp,
6897
+ ast.BinOp,
6898
+ ast.BoolOp,
6899
+ ast.Compare,
6900
+ ast.AugAssign
6901
+ )
6871
6902
  ):
6872
6903
  # Determine not/partial/full status of match...
6873
6904
  match: LiteralType[True, "partial", False] = False
@@ -7146,7 +7177,7 @@ which has slots that used to contain complex sub-objects replaced with
7146
7177
  `MemReference` objects. See `memoryMap`.
7147
7178
  """
7148
7179
 
7149
- SmallTypes: Tuple[Type] = (int, float, complex, bool, NoneType)
7180
+ SmallTypes: Tuple[Type, ...] = (int, float, complex, bool, NoneType)
7150
7181
  """
7151
7182
  The object types which are small enough to fit into a single field
7152
7183
  without using a pointer in theory, which we thus represent without using
@@ -7157,7 +7188,7 @@ with `isinstance`.
7157
7188
  # later so it cannot just be None. If we only wanted to support Python
7158
7189
  # 3.10+, we could use the union directly in isinstance.
7159
7190
 
7160
- SmallType: TypeAlias = Union[int, float, complex, bool, NoneType]
7191
+ SmallType: TypeAlias = Union[int, float, complex, bool, None]
7161
7192
  """
7162
7193
  A union of the `SmallTypes`.
7163
7194
  """
@@ -7231,6 +7262,7 @@ def memoryMap(
7231
7262
  or (INLINE_STRINGS_IN_MEMORY_REPORTS and isinstance(obj, str))
7232
7263
  ):
7233
7264
  # Simple values are used as-is:
7265
+ obj = cast(SmallType, obj)
7234
7266
  return None, obj
7235
7267
  elif isinstance(obj, (tuple, list, set)):
7236
7268
  # Structures are made shallow and referenced
@@ -9881,6 +9913,11 @@ def get_ref_src(src: str, node: ast.AST) -> str:
9881
9913
 
9882
9914
  # We're going to have to do this ourself: find the start of the
9883
9915
  # expression and state-machine to find its end
9916
+ if not hasattr(node, "lineno") or not hasattr(node, "col_offset"):
9917
+ raise TypeError(
9918
+ f"Node {node!r} is missing lineno and/or col_offset"
9919
+ f" attribute(s)."
9920
+ )
9884
9921
  start = get_src_index(src, node.lineno, node.col_offset)
9885
9922
 
9886
9923
  # Figure out the end point
@@ -518,8 +518,9 @@ All 4 expectation(s) were met.
518
518
  Code does not contain the expected structure:
519
519
  at least 1 definition(s) of functionName
520
520
  Although it does partially satisfy the requirement:
521
- Requirement partially satisfied via 0 full and 1 partial match(es):
521
+ Requirement partially satisfied via 0 full and 2 partial match(es):
522
522
  Partial match: FunctionDef on line 10
523
+ Partial match: FunctionDef on line 99
523
524
  checked code in file '{full_file}'""",
524
525
  "✓ {file}:44",
525
526
  """\
@@ -528,8 +529,9 @@ All 4 expectation(s) were met.
528
529
  at least 1 function definition(s) that also contain(s):
529
530
  at least 1 loop(s) or generator expression(s)
530
531
  Although it does partially satisfy the requirement:
531
- Requirement partially satisfied via 0 full and 1 partial match(es):
532
+ Requirement partially satisfied via 0 full and 2 partial match(es):
532
533
  Partial match: FunctionDef on line 10
534
+ Partial match: FunctionDef on line 99
533
535
  checked code in file '{full_file}'""",
534
536
  """\
535
537
  ✗ {file}:46
@@ -601,24 +603,36 @@ All 4 expectation(s) were met.
601
603
  Code does not contain the expected structure:
602
604
  at least 1 constant 2.0
603
605
  Although it does partially satisfy the requirement:
604
- Requirement partially satisfied via 0 full and 52 partial match(es):
606
+ Requirement partially satisfied via 0 full and 60 partial match(es):
605
607
  """ + ("""\
606
608
  Partial match: Constant on line 1
607
609
  Partial match: Constant on line 7""" if better_line_numbers else """\
608
610
  Partial match: Str on line 3
609
- Partial match: NameConstant on line 7"""), # not listing all 52...
611
+ Partial match: NameConstant on line 7"""), # not listing all 60...
610
612
  "✓ {file}:94",
611
613
  """\
612
614
  ✗ {file}:95
613
615
  Code does not contain the expected structure:
614
616
  at least 1 constant 5.0
615
617
  Although it does partially satisfy the requirement:
616
- Requirement partially satisfied via 0 full and 52 partial match(es):
618
+ Requirement partially satisfied via 0 full and 60 partial match(es):
617
619
  """ + ("""\
618
620
  Partial match: Constant on line 1
619
621
  Partial match: Constant on line 7""" if better_line_numbers else """\
620
622
  Partial match: Str on line 3
621
- Partial match: NameConstant on line 7"""), # not listing all 52...
623
+ Partial match: NameConstant on line 7"""), # not listing all 60...
624
+ "✓ {file}:104",
625
+ "✓ {file}:107",
626
+ """\
627
+ ✗ {file}:110
628
+ Code does not contain the expected structure:
629
+ at least 1 definition(s) of aug that also contain(s):
630
+ no operator '/'
631
+ Although it does partially satisfy the requirement:
632
+ Requirement partially satisfied via 0 full and 2 partial match(es):
633
+ Partial match: FunctionDef on line 99
634
+ Partial match: FunctionDef on line 10
635
+ """
622
636
  ],
623
637
 
624
638
  "reverse_tracing": [
@@ -1360,63 +1374,72 @@ def test_all():
1360
1374
  Tests each example file. The `examples` directory must be in the
1361
1375
  same place that this `test_examples.py` file lives.
1362
1376
  """
1363
- os.chdir(os.path.join(os.path.dirname(__file__), "examples"))
1364
- sys.path.insert(0, '.')
1365
- for (mname, inputs) in EXAMPLES:
1366
- optimism.detailLevel(0)
1367
- optimism.deleteAllTestSuites()
1368
- optimism.colors(False)
1369
- module, output, stdout = run_example(mname, inputs)
1370
- # Replace tracebacks with generic forms so we can match on
1371
- # specific errors being reported while ignoring the files & lines
1372
- # where they are reported.
1373
- stdout = re.sub(
1374
- r"Traceback \(most recent call last\):.*?^([ a-zA-Z]*Error:)",
1375
- "Traceback omitted\n\\1",
1376
- stdout,
1377
- flags=re.MULTILINE | re.DOTALL
1378
- )
1379
- output = re.sub(
1380
- r"Traceback \(most recent call last\):.*?^([ a-zA-Z]*Error:)",
1381
- "Traceback omitted\n\\1",
1382
- output,
1383
- flags=re.MULTILINE | re.DOTALL
1384
- )
1385
- #output = re.sub(r"Traceback \(most recent call last\).*?NameError:", "HAHAHA", output, flags=re.MULTILINE | re.DOTALL)
1386
- # Scrub line numbers from tracebacks so our expectations don't
1387
- # become hopelessly fragile
1388
- stdout = re.sub(r", line \d+,", ", line X,", stdout)
1389
- output = re.sub(r", line \d+,", ", line X,", output)
1390
- for ex in EXPECTATIONS[mname]:
1391
- exp = ex.format(
1392
- file=os.path.basename(module.__file__),
1393
- dir=(
1394
- os.path.split(module.__file__)[0] + '/'
1395
- if better_line_numbers
1396
- else ''
1397
- ),
1398
- full_file=module.__file__,
1399
- opt_file=optimism.__file__,
1377
+ olddir = os.getcwd()
1378
+ try:
1379
+ os.chdir(os.path.join(os.path.dirname(__file__), "examples"))
1380
+ sys.path.insert(0, '.')
1381
+ for (mname, inputs) in EXAMPLES:
1382
+ optimism.detailLevel(0)
1383
+ optimism.deleteAllTestSuites()
1384
+ optimism.colors(False)
1385
+ module, output, stdout = run_example(mname, inputs)
1386
+ # Replace tracebacks with generic forms so we can match on
1387
+ # specific errors being reported while ignoring the files & lines
1388
+ # where they are reported.
1389
+ stdout = re.sub(
1390
+ r"Traceback \(most recent call last\):.*?^([ a-zA-Z]*Error:)",
1391
+ "Traceback omitted\n\\1",
1392
+ stdout,
1393
+ flags=re.MULTILINE | re.DOTALL
1400
1394
  )
1401
- # Redundant, but makes issues easier to diagnose
1402
- for line in exp.splitlines():
1403
- if line not in output:
1404
- print("\n\nLINE:\n" + line)
1405
- print("\n\nOUTPUT:\n" + output)
1406
- assert (line in output), (line, output)
1407
- if exp not in output:
1408
- print("\n\nEXP:\n" + exp)
1409
- print("\n\nOUTPUT:\n" + output)
1410
- assert (exp in output), (exp, output)
1411
- if mname in STDOUT_EXPECT:
1412
- for ex in STDOUT_EXPECT[mname]:
1395
+ output = re.sub(
1396
+ r"Traceback \(most recent call last\):.*?^([ a-zA-Z]*Error:)",
1397
+ "Traceback omitted\n\\1",
1398
+ output,
1399
+ flags=re.MULTILINE | re.DOTALL
1400
+ )
1401
+ #output = re.sub(r"Traceback \(most recent call last\).*?NameError:", "HAHAHA", output, flags=re.MULTILINE | re.DOTALL)
1402
+ # Scrub line numbers from tracebacks so our expectations don't
1403
+ # become hopelessly fragile
1404
+ stdout = re.sub(r", line \d+,", ", line X,", stdout)
1405
+ output = re.sub(r", line \d+,", ", line X,", output)
1406
+ for ex in EXPECTATIONS[mname]:
1413
1407
  exp = ex.format(
1414
1408
  file=os.path.basename(module.__file__),
1415
- dir=os.path.split(module.__file__)[0],
1409
+ dir=(
1410
+ os.path.split(module.__file__)[0] + '/'
1411
+ if better_line_numbers
1412
+ else ''
1413
+ ),
1416
1414
  full_file=module.__file__,
1417
1415
  opt_file=optimism.__file__,
1418
1416
  )
1417
+ # Redundant, but makes issues easier to diagnose
1419
1418
  for line in exp.splitlines():
1420
- assert (line in stdout), stdout
1421
- assert (exp in stdout), stdout
1422
- os.chdir("..")
1419
+ if line not in output:
1420
+ print("\n\nLINE:\n" + line)
1421
+ print("\n\nOUTPUT:\n" + output)
1422
+ assert (line in output), (line, output)
1423
+ if exp not in output:
1424
+ print("\n\nEXP:\n" + exp)
1425
+ print("\n\nOUTPUT:\n" + output)
1426
+ assert (exp in output), (exp, output)
1427
+ if mname in STDOUT_EXPECT:
1428
+ for ex in STDOUT_EXPECT[mname]:
1429
+ exp = ex.format(
1430
+ file=os.path.basename(module.__file__),
1431
+ dir=os.path.split(module.__file__)[0],
1432
+ full_file=module.__file__,
1433
+ opt_file=optimism.__file__,
1434
+ )
1435
+ for line in exp.splitlines():
1436
+ assert (line in stdout), stdout
1437
+ assert (exp in stdout), stdout
1438
+ finally:
1439
+ os.chdir(olddir)
1440
+
1441
+
1442
+ if __name__ == "__main__":
1443
+ print('Testing example files...')
1444
+ test_all()
1445
+ print('...all tests passed.')
@@ -1,16 +1,15 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: optimism
3
- Version: 3.1.3
3
+ Version: 3.2
4
4
  Summary: Very simple testing framework suitable for beginner programmers, with easy functions for accomplishing most common testing tasks like providing input. Requires Python 3.8+.
5
5
  Home-page: https://cs.wellesley.edu/~pmwh/optimism/docs/optimism.html
6
6
  Author: Peter Mawhorter
7
7
  Author-email: pmawhort@wellesley.edu
8
- License: BSD 3-Clause License
8
+ License: LicenseRef-LLM-hostile_BSD
9
9
  Classifier: Programming Language :: Python :: 3 :: Only
10
10
  Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Intended Audience :: Education
12
12
  Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: BSD License
14
13
  Classifier: Operating System :: OS Independent
15
14
  Classifier: Natural Language :: English
16
15
  Classifier: Topic :: Education
@@ -19,6 +18,7 @@ Description-Content-Type: text/markdown
19
18
  License-File: LICENSE.txt
20
19
  Provides-Extra: test
21
20
  Requires-Dist: pytest; extra == "test"
21
+ Dynamic: license-file
22
22
 
23
23
  # `optimism`
24
24
 
@@ -33,6 +33,17 @@ Designed by Peter Mawhorter.
33
33
  Works on Python versions 3.7 and up, with 3.9+ recommended.
34
34
 
35
35
 
36
+ ## Note on Large Language Models
37
+
38
+ This project has a zero-tolerance policy for the use of large language
39
+ models to write code, process the code or outputs from this project, or
40
+ otherwise interact with this project in any way. If you choose to violate
41
+ this policy, be aware that the code, text, and outputs of this project
42
+ may cause (more) unpredictable (than usual) behavior in LLM systems that
43
+ interact with them. See `LICENSE.txt` for license restrictions and
44
+ disclaimers, and `AGENTS.md` for an example.
45
+
46
+
36
47
  ## Installing
37
48
 
38
49
  To install from PyPI, run the following command on the command-line:
@@ -7,13 +7,12 @@ long_description_content_type = text/markdown
7
7
  url = https://cs.wellesley.edu/~pmwh/optimism/docs/optimism.html
8
8
  author = Peter Mawhorter
9
9
  author_email = pmawhort@wellesley.edu
10
- license = BSD 3-Clause License
10
+ license = LicenseRef-LLM-hostile_BSD
11
11
  classifiers =
12
12
  Programming Language :: Python :: 3 :: Only
13
13
  Development Status :: 4 - Beta
14
14
  Intended Audience :: Education
15
15
  Intended Audience :: Developers
16
- License :: OSI Approved :: BSD License
17
16
  Operating System :: OS Independent
18
17
  Natural Language :: English
19
18
  Topic :: Education
@@ -1,32 +0,0 @@
1
- Copyright (c) 2021-2022
2
- Peter Mawhorter
3
- Wellesley College
4
- All rights reserved.
5
-
6
- Redistribution and use in source and binary forms, with or without
7
- modification, are permitted provided that the following conditions are
8
- met:
9
-
10
- 1. Redistributions of source code must retain the above copyright
11
- notice, this list of conditions and the following disclaimer.
12
-
13
- 2. Redistributions in binary form must reproduce the above copyright
14
- notice, this list of conditions and the following disclaimer in the
15
- documentation and/or other materials provided with the
16
- distribution.
17
-
18
- 3. Neither the name of the copyright holder nor the names of its
19
- contributors may be used to endorse or promote products derived
20
- from this software without specific prior written permission.
21
-
22
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
File without changes
File without changes
File without changes
File without changes