From bd2e62fd351f92ff1a26f32f8a44c866dfed63e2 Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 15:55:39 +0100 Subject: [PATCH 01/11] Switch to setup.cfg, bump version --- pyproject.toml | 3 +++ setup.cfg | 43 +++++++++++++++++++++++++++++++++++++++++++ setup.py | 40 ---------------------------------------- 3 files changed, 46 insertions(+), 40 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..fed528d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" diff --git a/setup.cfg b/setup.cfg index 3c6e79c..4d553cf 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,45 @@ +[metadata] +name = dice +version = 4.0.0 +author = Sam Clements +author_email = sam@borntyping.co.uk +license = MIT +description = A library for parsing and evaluating dice notation +url = https://github.com/borntyping/python-dice +long_description = file: README.rst +classifiers = + Development Status :: 6 - Mature + Environment :: Console + Intended Audience :: Developers + Intended Audience :: Other Audience + License :: OSI Approved :: MIT License + Operating System :: OS Independent + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 + Topic :: Games/Entertainment + Topic :: Games/Entertainment :: Board Games + Topic :: Games/Entertainment :: Role-Playing + Topic :: Games/Entertainment :: Multi-User Dungeons (MUD) + Topic :: Games/Entertainment :: Turn Based Strategy + Topic :: Utilities + +[options] +packages = find: +install_requires = + docopt>=0.6.1 + pyparsing>=2.4.1 + +[options.entry_points] +console_scripts = + dice = dice.command:main + roll = dice.command:main + [bdist_wheel] universal=1 diff --git a/setup.py b/setup.py deleted file mode 100644 index e56c6fd..0000000 --- a/setup.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python - -from __future__ import absolute_import, print_function, unicode_literals -from setuptools import setup, find_packages - -setup( - name="dice", - version="3.1.2", - author="Sam Clements", - author_email="sam@borntyping.co.uk", - url="https://github.com/borntyping/python-dice", - description="A library for parsing and evaluating dice notation", - long_description=open("README.rst").read(), - license="MIT", - packages=find_packages(), - install_requires=["docopt>=0.6.1", "pyparsing>=2.4.1"], - entry_points={ - "console_scripts": ["dice = dice.command:main", "roll = dice.command:main"] - }, - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "Intended Audience :: Developers", - "Intended Audience :: Other Audience", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Topic :: Games/Entertainment", - "Topic :: Games/Entertainment :: Board Games", - "Topic :: Games/Entertainment :: Role-Playing", - "Topic :: Games/Entertainment :: Multi-User Dungeons (MUD)", - "Topic :: Games/Entertainment :: Turn Based Strategy", - "Topic :: Utilities", - ], -) From c90d3a466cae83943f5856e786e9b440c3a01ac3 Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 15:59:18 +0100 Subject: [PATCH 02/11] Get tests working again --- .gitignore | 3 +++ dice/grammar.py | 10 ++++++++-- dice/tests/test_utilities.py | 17 ----------------- dice/utilities.py | 34 ---------------------------------- tox.ini | 3 +-- 5 files changed, 12 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index 7a31679..76eefed 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,10 @@ *.pyc .cache/ .coverage +.idea/ .pytest_cache/ +.tox/ +.venv/ __pycache__/ build/ dist/ diff --git a/dice/grammar.py b/dice/grammar.py index d62040e..b0bcfc6 100644 --- a/dice/grammar.py +++ b/dice/grammar.py @@ -8,12 +8,15 @@ from __future__ import absolute_import, print_function, unicode_literals +import warnings + from pyparsing import ( CaselessLiteral, Forward, Literal, OneOrMore, Or, + ParserElement, StringStart, StringEnd, Suppress, @@ -50,9 +53,12 @@ Again, ) -from dice.utilities import patch_pyparsing, wrap_string +from dice.utilities import wrap_string -patch_pyparsing() +# Enables pyparsing's packrat parsing, which is much faster +# for the type of parsing being done in this library. +warnings.warn("Enabled pyparsing packrat parsing", ImportWarning) +ParserElement.enablePackrat() def operatorPrecedence(base, operators): diff --git a/dice/tests/test_utilities.py b/dice/tests/test_utilities.py index ebdfdb8..eeab22c 100644 --- a/dice/tests/test_utilities.py +++ b/dice/tests/test_utilities.py @@ -17,23 +17,6 @@ def test_enable_pyparsing_packrat_parsing(): assert pyparsing.ParserElement._packratEnabled is True -def test_disable_pyparsing_arity_trimming(): - """Test that pyparsing._trim_arity has been replaced""" - import pyparsing - import dice.utilities - - assert pyparsing._trim_arity is dice.utilities._trim_arity - - -def test_disable_pyparsing_arity_trimming_works(): - """Tests that arity trimming has been disabled and parse actions with - the wrong number of arguments will raise TypeErrors""" - for func in [lambda a: None, lambda a, b: None, lambda a, b, c, d: None]: - element = Literal("test").setParseAction(func) - with raises(TypeError): - element.parseString("test") - - class TestVerbosePrint(object): def _get_vprint(self, expr): raw = roll(expr, raw=True) diff --git a/dice/utilities.py b/dice/utilities.py index a2daea0..a9292c8 100644 --- a/dice/utilities.py +++ b/dice/utilities.py @@ -2,7 +2,6 @@ import dice.elements from dice.constants import VERBOSE_INDENT -import warnings import pyparsing @@ -16,39 +15,6 @@ def single(iterable): return iterable[0] if len(iterable) == 1 else iterable -def patch_pyparsing(packrat=True, arity=True): - """Applies monkey-patches to pyparsing""" - if packrat: - enable_pyparsing_packrat() - - if arity: - disable_pyparsing_arity_trimming() - - -def enable_pyparsing_packrat(): - """Enables pyparsing's packrat parsing, which is much faster for the type - of parsing being done in this library""" - warnings.warn("Enabled pyparsing packrat parsing", ImportWarning) - pyparsing.ParserElement.enablePackrat() - - -def _trim_arity(func, maxargs=None): - def wrapper(string, location, tokens): - return func(string, location, tokens) - - return wrapper - - -def disable_pyparsing_arity_trimming(): - """When pyparsing encounters a TypeError when calling a parse action, it - will keep trying the call the function with one less argument each time - until it succeeds. This disables this functionality, as it catches - TypeErrors raised by other functions and makes debugging those functions - very hard to do.""" - warnings.warn("Disabled pyparsing arity trimming", ImportWarning) - pyparsing._trim_arity = _trim_arity - - def wrap_string(cls, *args, **kwargs): suppress = kwargs.pop("suppress", True) e = cls(*args, **kwargs) diff --git a/tox.ini b/tox.ini index 790ddce..19c58e8 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,6 @@ [tox] minversion=1.5.0 -toxworkdir=.cache -envlist=py27,py35,py36,py37,py38,py39,pypy,pypy3 +envlist=py37,py38,py39,py310,py311,py312 skip_missing_interpreters=true [testenv] From 5d0bc2e2bd1638adf4831dd34da5134c34c15f61 Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 16:31:49 +0100 Subject: [PATCH 03/11] Use pyproject.toml for metadata, update README --- .envrc | 3 - LICENCE => LICENSE.md | 2 +- README.md | 160 +++++++++++++++++++++++++++++++++++ README.rst | 192 ------------------------------------------ pyproject.toml | 48 +++++++++++ setup.cfg | 45 ---------- 6 files changed, 209 insertions(+), 241 deletions(-) delete mode 100644 .envrc rename LICENCE => LICENSE.md (94%) create mode 100644 README.md delete mode 100644 README.rst delete mode 100644 setup.cfg diff --git a/.envrc b/.envrc deleted file mode 100644 index 0d15505..0000000 --- a/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -layout_pipenv diff --git a/LICENCE b/LICENSE.md similarity index 94% rename from LICENCE rename to LICENSE.md index 165f017..57860be 100644 --- a/LICENCE +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013 Sam Clements +Copyright (c) 2013-2023 Sam Clements, 2017 Caleb Johnson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/README.md b/README.md new file mode 100644 index 0000000..a127a29 --- /dev/null +++ b/README.md @@ -0,0 +1,160 @@ +# dice + +A Python library and command line tool for parsing and evaluating dice notation. + +_I consider this library "finished", and don't expect to add any more features to it. Bug and security fixes may still be released, especially if you find any bugs after all this time. If you're interested in other libraries in this space, [dyce] has [a great comparison table][comparison-to-alternatives] of Python dice rolling libraries._ + +[dyce]: https://posita.github.io/dyce/latest/ +[comparison-to-alternatives]: https://posita.github.io/dyce/0.6/#comparison-to-alternatives + +## Quickstart + +### Command-line + +```shell +$ roll 3d6 +``` + +The command line arguments are as follows: + +* `-m` `--min` Make all rolls the lowest possible result +* `-M` `--max` Make all rolls the highest possible result +* `-h` `--help` Show this help text +* `-v` `--verbose` Show additional output +* `-V` `--version` Show the package version + +If your expression begins with a dash (`-`), then put a double dash (`--`) +before it to prevent docopt from trying to process it as a command option. +Example: `roll -- -10d6`. Alternatively, use parenthesis: `roll (-10d6)`. + +### Python API + +Invoking from python: + +```python +import dice +dice.roll('3d6') +``` + +This returns an `Element` which is the result of the roll, which can be a +`list`, `int`, or subclass thereof, depending on the top-level operator. + +## Usage + +### Notation + +The expression works like a simple equation parser with some extra operators. + +*The following operators are listed in order of precedence. Parentheses may +be used to force an alternate order of evaluation.* + +The dice (`[N]dS`) operator takes an amount (N) and a number of sides (S), and +returns a list of N random numbers between 1 and S. For example: `4d6` may +return `[6, 3, 2, 4]`. Using a `%` as the second operand is shorthand for +rolling a d100, and a using `f` is shorthand for ±1 fudge dice. + +The fudge dice (`[N]uS`) operator is interchangeable with the dice operator, +but makes the dice range from -S to S instead of 1 to S. This includes 0. + +A wild dice (`[N]wS`) roll is special. The last roll in this set is called the +"wild die". If this die's roll is the maximum value, the second-highest roll +in the set is set to the maximum value. If its roll is the minimum, then +both it and the highest roll in the set aer set to zero. Then another die is +rolled. If this roll is the minimum value again, then ALL die are set to zero. +If a single-sided wild die is rolled, the roll behaves like a normal one. + +If N is not specified, it is assumed you want to roll a single die. +`d6` is equivalent to `1d6`. + +Rolls can be exploded with the `x` operator, which adds additional dice +to the set for each roll above a given threshold. If a threshold isn't given, +it defaults to the maximum possible roll. If the extra dice exceed this +threshold, they "explode" again! Safeguards are in place to prevent this from +crashing the parser with infinite explosions. + +You can make the parser re-roll dice below a certain threshold with the `r` +and `rr` operators. The single `r` variety allows the new roll to be below +the threshold, whereas the double variety's roll *changes* the roll range to +have a minimum of the threshold. The threshold defaults to the minimum roll. + +The highest, middle or lowest rolls or list entries can be selected with +(`^` or `h`), (`m` or `o`), or (`v` or `l`) respectively. +`6d6^3` will keep the highest 3 rolls, whereas `6d6v3` will select +the lowest 3 rolls. If a number isn't specified, it defaults to keeping all +but one for highest and lowest, and all but two for the middle. If a negative +value is given as the operand for any of these operators, this operation will +drop that many elements from the result. For example, `6d6^-2` will drop the +two lowest values from the set, leaving the 4 highest. Zero has no effect. + +A variant of the "explode" operator is the `a` ("again") operator. Instead of +re-rolling values equal to or greater than the threshold (or max value), this +operator doubles values *equal* to the provided threshold (or max value). When +no right-side operand is specified, the left side must be a dice expression. + +There are two operators for taking a set of rolls or numbers and counting the +number of elements at or above a certain threshold, or "successes". Both +require a right-hand operand for the threshold. The first, `e`, only counts +successes. The second, `f`, counts successes minus failures, which are when +a roll is the minimum possible value for the die element, or 1 for lists. + +A list or set of rolls can be turned into an integer with the total (`t`) +operator. `6d1t` will return `6` instead of `[1, 1, 1, 1, 1, 1]`. +Applying integer operations to a list of rolls will total them automatically. + +A set of dice rolls can be sorted with the sort (`s`) operator. `4d6s` +will not change the return value, but the dice will be sorted from lowest to +highest. + +The `+-` operator is a special prefix for sets of rolls and lists. It +negates odd roles within a list. Example: `[1, 2, 3]` -> `[-1, 2, -3]`. +There is also a negate (`-`) operator, which works on either single +elements, sets or rolls, or lists. There is also an identity `+` operator. + +Values can be added or subtracted from each element of a list or set of rolls +with the point-wise add (`.+`) and subtract (`.-`) operators. For example: +`4d1 .+ 3` will return `[4, 4, 4, 4]`. + +Basic integer operations are also available: `(16 / 8 * 4 - 2 + 1) % 4 -> 3`. + + +Finally, there are two operators for building and extending lists. To build a +list, use a comma to separate elements. If any comma-seperated item isn't a +scalar (e.g. a roll), it is flattened into one by taking its total. The +"extend" operator (`|`) is used to merge two lists into one, or append single +elements to the beginning or end of a list. + +### Python API + +The calls to `dice.roll()` above may be replaced with `dice.roll_min()` or +`dice.roll_max()` to force ALL rolls to their highest or lowest values +respectively. This might be useful to see what the minimum and maximum +possible values for a given expression are. Beware that this causes wild dice +rolls to act like normal ones, and rolls performed as explosions are not +forced high or low. + +The `roll()` function and variants take a boolean `raw` parameter which +makes the library return the element instead of the result. Note that the +`evaluate_cached` method is called as part of `roll()`, which populates +`element.result`. Calling `element.evaluate()` will not reset this value. + +To display a verbose breakdown of the element tree, the +`dice.utilities.verbose_print(element)` function is available. +If `element.result` has not yet been populated, the function calls +`evaluate_cached()` first. Keep this in mind if you want to print the result +of an evaluation with custom arguments. `verbose_print()` returns a `str`. + +Most evaluation errors will raise `DiceError` or `DiceFatalError`, both of +which are subclasses of `DiceBaseError`. These exceptions have a method +named `pretty_print`, which will output a string indicating where the error +happened:: + +```python-repl +>>> try: +... dice.roll('1/0') +... except dice.DiceBaseException as e: +... print(e.pretty_print()) +... +1/0 + ^ Division by zero +>>> +``` diff --git a/README.rst b/README.rst deleted file mode 100644 index 3c05183..0000000 --- a/README.rst +++ /dev/null @@ -1,192 +0,0 @@ -==== -dice -==== - -.. image:: https://img.shields.io/pypi/v/dice.svg - :target: https://pypi.python.org/pypi/dice - :alt: Latest PyPI version - -.. image:: https://img.shields.io/travis/borntyping/python-dice.svg - :target: https://travis-ci.org/borntyping/python-dice - :alt: Travis-CI build status - -.. image:: https://coveralls.io/repos/github/borntyping/python-dice/badge.svg - :target: https://coveralls.io/github/borntyping/python-dice - :alt: Coveralls coverage score - - -A library and command line tool for parsing and evaluating dice notation. - -Usage -===== - -From the command line, as a pip-installed entry point:: - - $ roll 3d6 - -or as a module:: - - $ python -m dice 3d6 - -The command line arguments are as follows:: - - -m --min Make all rolls the lowest possible result - -M --max Make all rolls the highest possible result - -h --help Show this help text - -v --verbose Show additional output - -V --version Show the package version - -If your expression begins with a dash (``-``), then put a double dash (``--``) -before it to prevent docopt from trying to process it as a command option. -Example: ``roll -- -10d6``. Alternatively, use parenthesis: ``roll (-10d6)``. - -Invoking from python:: - - import dice - dice.roll('3d6') - -This returns an ``Element`` which is the result of the roll, which can be a -``list``, ``int``, or subclass thereof, depending on the top-level operator. - -Notation -======== - -The expression works like a simple equation parser with some extra operators. - -*The following operators are listed in order of precedence. Parentheses may -be used to force an alternate order of evaluation.* - -The dice (``[N]dS``) operator takes an amount (N) and a number of sides (S), and -returns a list of N random numbers between 1 and S. For example: ``4d6`` may -return ``[6, 3, 2, 4]``. Usin a ``%`` as the second operand is shorthand for -rolling a d100, and a using ``f`` is shorthand for ±1 fudge dice. - -The fudge dice (``[N]uS``) operator is interchangable with the dice operator, -but makes the dice's range from -S to S instead of 1 to S. This includes 0. - -A wild dice (``[N]wS``) roll is special. The last roll in this set is called the -"wild die". If this die's roll is the maximum value, the second-highest roll -in the set is set to the maximum value. If its roll is the minimum, then -both it and the highest roll in the set aer set to zero. Then another die is -rolled. If this roll is the minimum value again, then ALL die are set to zero. -If a single-sided wild die is rolled, the roll behaves like a normal one. - -If N is not specified, it is assumed you want to roll a single die. -``d6`` is equivalent to ``1d6``. - -Rolls can be exploded with the ``x`` operator, which adds an additional dice -to the set for each roll above a given threshold. If a threshold isn't given, -it defaults to the maximum possible roll. If the extra dice exceed this -threshold, they "explode" again! Safeguards are in place to prevent this from -crashing the parser with infinite explosions. - -You can make the parser reroll dice below a certain threshold with the ``r`` -and ``rr`` operators. The single ``r`` variety allows the new roll to be below -the threshold, whereas the double variety's roll *changes* the roll range to -have a minimum of the threshold. The threshold defaults to the minimum roll. - -The highest, middle or lowest rolls or list entries can be selected with -(``^`` or ``h``), (``m`` or ``o``), or (``v`` or ``l``) respectively. -``6d6^3`` will keep the highest 3 rolls, whereas ``6d6v3`` will select -the lowest 3 rolls. If a number isn't specified, it defaults to keeping all -but one for highest and lowest, and all but two for the middle. If a negative -value is given as the operand for any of these operators, this operation will -drop that many elements from the result. For example, ``6d6^-2`` will drop the -two lowest values from the set, leaving the 4 highest. Zero has no effect. - -A variant of the explode operator is the ``a`` ("again") operator. Instead of -re-rolling values equal to or greater than the threshold (or max value), this -operator doubles values *equal* to the provided threshold (or max value). When -no right-side operand is specified, the left side must be a dice expression. - -There are two operators for taking a set of rolls or numbers and counting the -number of elements at or above a certain threshold, or "successes". Both -require a right-hand operand for the threshold. The first, ``e``, only counts -successes. The second, ``f``, counts successes minus failures, which are when -a roll is the minimum possible value for the die element, or 1 for lists. - -A list or set of rolls can be turned into an integer with the total (``t``) -operator. ``6d1t`` will return ``6`` instead of ``[1, 1, 1, 1, 1, 1]``. -Applying integer operations to a list of rolls will total them automatically. - -A set of dice rolls can be sorted with the sort (``s``) operator. ``4d6s`` -will not change the return value, but the dice will be sorted from lowest to -highest. - -The ``+-`` operator is a special prefix for sets of rolls and lists. It -negates odd roles within a list. Example: ``[1, 2, 3]`` -> ``[-1, 2, -3]``. -There is also a negate (``-``) operator, which works on either single -elements, sets or rolls, or lists. There is also an identity ``+`` operator. - -Values can be added or subtracted from each element of a list or set of rolls -with the pointwise add (``.+``) and subtract (``.-``) operators. For example: -``4d1 .+ 3`` will return ``[4, 4, 4, 4]``. - -Basic integer operations are also available: ``(16 / 8 * 4 - 2 + 1) % 4 -> 3``. - - -Finally, there are two operators for building and extending lists. To build a -list, use a comma to seperate elements. If any comma-seperated item isn't a -scalar (e.g. a roll), it is flattened into one by taking its total. The -extend operator (``|``) is used to merge two lists into one, or append single -elements to the beginning or end of a list. - -API -=== - -The calls to ``dice.roll()`` above may be replaced with ``dice.roll_min()`` or -``dice.roll_max()`` to force ALL rolls to their highest or lowest values -respectively. This might be useful to see what the minumum and maximum -possible values for a given expression are. Beware that this causes wild dice -rolls to act like normal ones, and rolls performed as explosions are not -forced high or low. - -The ``roll()`` function and variants take a boolean ``raw`` parameter which -makes the library return the element instead of the result. Note that the -``evaluate_cached`` method is called as part of ``roll()``, which populates -``element.result``. Calling ``element.evaluate()`` will not reset this value. - -To display a verbose breakdown of the element tree, the -``dice.utilities.verbose_print(element)`` function is available. -If ``element.result`` has not yet been populated, the function calls -``evaluate_cached()`` first. Keep this in mind if you want to print the result -of an evaluation with custom arguments. ``verbose_print()`` returns a ``str``. - -Most evaluation errors will raise ``DiceError`` or ``DiceFatalError``, both of -which are subclasses of ``DiceBaseError``. These exceptions have a method -named ``pretty_print``, which will output a string indicating where the error -happened:: - - >>> try: - ... dice.roll('1/0') - ... except dice.DiceBaseException as e: - ... print(e.pretty_print()) - ... - 1/0 - ^ Division by zero - >>> - -Licence -======= - -The MIT License (MIT) - -Copyright (c) 2013 Sam Clements, 2017 Caleb Johnson - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/pyproject.toml b/pyproject.toml index fed528d..ddb86ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,51 @@ [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" + +[project] +name = "dice" +version = "4.0.0" +authors = [ + { name = "Sam Clements", email = "sam@borntyping.co.uk" }, + { name = "Caleb Johnson" }, +] +maintainers = [ + { name = "Sam Clements", email = "sam@borntyping.co.uk" }, +] +description = "A library for parsing and evaluating dice notation" +readme = "README.md" +requires-python = ">=3.7" +license = { text = "MIT" } +classifiers = [ + "Development Status :: 6 - Mature", + "Environment :: Console", + "Intended Audience :: Developers", + "Intended Audience :: Other Audience", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Games/Entertainment", + "Topic :: Games/Entertainment :: Board Games", + "Topic :: Games/Entertainment :: Role-Playing", + "Topic :: Games/Entertainment :: Multi-User Dungeons (MUD)", + "Topic :: Games/Entertainment :: Turn Based Strategy", + "Topic :: Utilities", +] +keywords = ["dice"] +dependencies = [ + "docopt>=0.6.1", + "pyparsing>=2.4.1", +] +urls = { homepage = "https://github.com/borntyping/python-dice" } + +[project.scripts] +dice = "dice.command:main" +roll = "dice.command:main" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 4d553cf..0000000 --- a/setup.cfg +++ /dev/null @@ -1,45 +0,0 @@ -[metadata] -name = dice -version = 4.0.0 -author = Sam Clements -author_email = sam@borntyping.co.uk -license = MIT -description = A library for parsing and evaluating dice notation -url = https://github.com/borntyping/python-dice -long_description = file: README.rst -classifiers = - Development Status :: 6 - Mature - Environment :: Console - Intended Audience :: Developers - Intended Audience :: Other Audience - License :: OSI Approved :: MIT License - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: 3.12 - Topic :: Games/Entertainment - Topic :: Games/Entertainment :: Board Games - Topic :: Games/Entertainment :: Role-Playing - Topic :: Games/Entertainment :: Multi-User Dungeons (MUD) - Topic :: Games/Entertainment :: Turn Based Strategy - Topic :: Utilities - -[options] -packages = find: -install_requires = - docopt>=0.6.1 - pyparsing>=2.4.1 - -[options.entry_points] -console_scripts = - dice = dice.command:main - roll = dice.command:main - -[bdist_wheel] -universal=1 From fb99175c0aa567d56ece91d665796ce5f11b166d Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 16:34:41 +0100 Subject: [PATCH 04/11] Add installation instructions to README --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index a127a29..ff86b3a 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,15 @@ This returns an `Element` which is the result of the roll, which can be a ## Usage +### Installation + +This library is available as `dice` on PyPI. Install it with your Python +package or dependency manager of choice — if you're installing it as a +command-line tool, I recommend [pipx]. It's only dependencies are the `docopt` +and `pyparsing` libraries. + +[pipx]: https://pypa.github.io/pipx/ + ### Notation The expression works like a simple equation parser with some extra operators. From 4da1f7b082144c3ce900fea647567d138e903edd Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 16:40:37 +0100 Subject: [PATCH 05/11] Drop Python 2 syntax --- README.md | 8 ++++++-- dice/__init__.py | 2 -- dice/__main__.py | 2 -- dice/command.py | 2 -- dice/constants.py | 2 +- dice/elements.py | 14 ++++++-------- dice/grammar.py | 2 -- dice/tests/test_command.py | 2 -- dice/tests/test_elements.py | 14 ++++++-------- dice/tests/test_grammar.py | 20 +++++++++----------- dice/tests/test_utilities.py | 6 ++---- dice/utilities.py | 3 --- pyproject.toml | 2 -- tox.ini | 2 +- 14 files changed, 31 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index ff86b3a..b7dbfed 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,12 @@ This returns an `Element` which is the result of the roll, which can be a This library is available as `dice` on PyPI. Install it with your Python package or dependency manager of choice — if you're installing it as a -command-line tool, I recommend [pipx]. It's only dependencies are the `docopt` -and `pyparsing` libraries. +command-line tool, I recommend [pipx]. + +A recent version of Python 3 (3.8 or above) is required. You can probably run +it or easily adapt it for older versions of Python, but I don't support any +end-of-life Python versions. Beyond that, the only dependencies are the +`docopt` and `pyparsing` libraries. [pipx]: https://pypa.github.io/pipx/ diff --git a/dice/__init__.py b/dice/__init__.py index bd6ab19..55c03e2 100644 --- a/dice/__init__.py +++ b/dice/__init__.py @@ -1,7 +1,5 @@ """A library for parsing and evaluating dice notation.""" -from __future__ import absolute_import, print_function, unicode_literals - from pyparsing import ParseBaseException import dice.elements diff --git a/dice/__main__.py b/dice/__main__.py index df125e4..1465fb8 100644 --- a/dice/__main__.py +++ b/dice/__main__.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, unicode_literals - import sys import dice.command diff --git a/dice/command.py b/dice/command.py index d4fcfef..136540b 100644 --- a/dice/command.py +++ b/dice/command.py @@ -11,8 +11,6 @@ -V --version Show the package version """ -from __future__ import absolute_import, print_function, unicode_literals - import docopt import dice diff --git a/dice/constants.py b/dice/constants.py index 939c990..f8b38b9 100644 --- a/dice/constants.py +++ b/dice/constants.py @@ -1,5 +1,5 @@ # Python 2 doesn't nave enum, but this is close enough. -class DiceExtreme(object): +class DiceExtreme: EXTREME_MIN = "MIN" EXTREME_MAX = "MAX" diff --git a/dice/elements.py b/dice/elements.py index e540a0c..59099be 100644 --- a/dice/elements.py +++ b/dice/elements.py @@ -1,7 +1,5 @@ """Objects used in the evaluation of the parse tree""" -from __future__ import absolute_import, print_function, unicode_literals - import random import operator from pyparsing import ParseFatalException @@ -12,7 +10,7 @@ from dice.utilities import classname, add_even_sub_odd, dice_switch -class Element(object): +class Element: @classmethod def parse(cls, string, location, tokens): try: @@ -197,7 +195,7 @@ def __init__(self, element, rolled=None, **kwargs): else: rolled = self.do_roll(**kwargs) - super(Roll, self).__init__(rolled) + super().__init__(rolled) def copy(self): return type(self)( @@ -245,7 +243,7 @@ class ExplodedRoll(Roll): """Represents an exploded roll""" def __init__(self, original, rolled, **kwargs): - super(ExplodedRoll, self).__init__(original, rolled=rolled, **kwargs) + super().__init__(original, rolled=rolled, **kwargs) class RandomElement(Element): @@ -337,7 +335,7 @@ class Dice(RandomElement): SEPARATOR = "d" def __init__(self, amount, max_value, min_value=1): - super(Dice, self).__init__(amount, min_value, max_value) + super().__init__(amount, min_value, max_value) self.original_operands = (amount, max_value) @property @@ -371,7 +369,7 @@ class FudgeDice(Dice): SEPARATOR = "u" def __init__(self, amount, value): - super(FudgeDice, self).__init__(amount, value, -value) + super().__init__(amount, value, -value) def __repr__(self): p = "{0!r}, {1!r}".format(self.amount, self.max_value) @@ -779,7 +777,7 @@ def __new__(cls, x): # Passthrough to prevent Negate() clutter return Integer(-x) - return super(Negate, cls).__new__(cls) + return super().__new__(cls) def function(self, operand): operand = IntegerList(operand) diff --git a/dice/grammar.py b/dice/grammar.py index b0bcfc6..f694cbf 100644 --- a/dice/grammar.py +++ b/dice/grammar.py @@ -6,8 +6,6 @@ module for more information. """ -from __future__ import absolute_import, print_function, unicode_literals - import warnings from pyparsing import ( diff --git a/dice/tests/test_command.py b/dice/tests/test_command.py index ef5088e..63b9411 100644 --- a/dice/tests/test_command.py +++ b/dice/tests/test_command.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from dice import roll, roll_min, roll_max from dice.command import main from itertools import product diff --git a/dice/tests/test_elements.py b/dice/tests/test_elements.py index 78230db..bf19ee7 100644 --- a/dice/tests/test_elements.py +++ b/dice/tests/test_elements.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from dice.constants import DiceExtreme from dice.exceptions import DiceException, DiceFatalException import pickle @@ -21,7 +19,7 @@ from dice import roll, roll_min, roll_max -class TestElements(object): +class TestElements: def test_integer(self): assert isinstance(Integer(1), int) @@ -110,7 +108,7 @@ def test_wild_critfail(self): break -class TestErrors(object): +class TestErrors: def test_toomanydice(self): with raises(DiceFatalException): roll("%id6" % (MAX_ROLL_DICE + 1)) @@ -144,7 +142,7 @@ def test_invalid_wrap(self): raise DiceException.from_other(e) -class TestEvaluate(object): +class TestEvaluate: def test_cache(self): """Test that evaluation returns the same result on successive runs""" roll("6d(6d6)t") @@ -167,7 +165,7 @@ def test_multiargs(self): assert roll("1d1/1d1/1d1") == 1 -class TestRegisterDice(object): +class TestRegisterDice: def test_reregister(self): class FooDice(RandomElement): SEPARATOR = "d" @@ -190,7 +188,7 @@ class BazDice(Element): RandomElement.register_dice(BazDice) -class TestSystemRandom(object): +class TestSystemRandom: sysrandom = random.SystemRandom() # lowest, middle and highest operators use shuffle() @@ -201,7 +199,7 @@ def test_sysrandom_roll(self): roll("6d6", random=self.sysrandom) -class TestPickle(object): +class TestPickle: for expr in [ '-d20', '4d6t', diff --git a/dice/tests/test_grammar.py b/dice/tests/test_grammar.py index 5dcc88a..560428e 100644 --- a/dice/tests/test_grammar.py +++ b/dice/tests/test_grammar.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, unicode_literals, division - from pyparsing import Word, opAssoc from dice.elements import Integer, Roll, WildRoll, ExplodedRoll from dice.exceptions import DiceException, DiceFatalException @@ -7,7 +5,7 @@ from pytest import raises -class TestInteger(object): +class TestInteger: def test_value(self): assert roll("1337") == 1337 @@ -16,7 +14,7 @@ def test_type(self): assert isinstance(roll("1"), Integer) -class TestDice(object): +class TestDice: def test_dice_value(self): assert 0 < int(roll("d6")) <= 6 assert 0 < int(roll("6d6")) <= 36 @@ -61,7 +59,7 @@ def test_nested_dice(self): assert -6 <= roll("u(d6)t") <= 6 -class TestOperators(object): +class TestOperators: def test_add(self): assert roll("2 + 2") == 4 @@ -94,7 +92,7 @@ def test_aeso(self): assert roll("+-(1, 2)") == [-1, 2] -class TestVectorOperators(object): +class TestVectorOperators: def test_total(self): assert (6 * 1) <= roll("6d6t") <= (6 * 6) @@ -192,7 +190,7 @@ def test_extend(self): assert len(rr3) == 10 -class TestDiceOperators(object): +class TestDiceOperators: def test_reroll(self): r = roll("6d6r") assert len(r) == 6 @@ -228,7 +226,7 @@ def test_again_vector(self): assert roll("(1|1|1)a1") == [1, 1, 1, 1, 1, 1] -class TestErrors(object): +class TestErrors: @staticmethod def run_test(expr): with raises((DiceException, DiceFatalException)): @@ -266,7 +264,7 @@ def test_again_fail(self): self.run_test("1a") -class TestOperatorPrecedence(object): +class TestOperatorPrecedence: def test_operator_precedence_1(self): assert roll("16 / 8 * 4 + 2 - 1") == 9 @@ -280,7 +278,7 @@ def test_operator_precedence_4(self): assert roll("1 + 2 * 3") == 7 -class TestExpression(object): +class TestExpression: def test_expression(self): assert isinstance(roll("2d6"), Roll) @@ -288,7 +286,7 @@ def test_sub_expression(self): assert isinstance(roll("(2d6)d(2d6)"), Roll) -class TestBadPrecedence(object): +class TestBadPrecedence: def test_invalid_arity(self): with raises(Exception): grammar.operatorPrecedence( diff --git a/dice/tests/test_utilities.py b/dice/tests/test_utilities.py index eeab22c..0fbfa26 100644 --- a/dice/tests/test_utilities.py +++ b/dice/tests/test_utilities.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from pyparsing import Literal, ParseFatalException from pytest import raises import random @@ -17,7 +15,7 @@ def test_enable_pyparsing_packrat_parsing(): assert pyparsing.ParserElement._packratEnabled is True -class TestVerbosePrint(object): +class TestVerbosePrint: def _get_vprint(self, expr): raw = roll(expr, raw=True) evaluated = raw.evaluate_cached() @@ -51,7 +49,7 @@ def test_single_line(self): assert len(v.split("\n")) == 1 -class TestDiceSwitch(object): +class TestDiceSwitch: def test_separator_map(self): for sep, cls in RandomElement.DICE_MAP.items(): d = utilities.dice_switch(6, 6, sep) diff --git a/dice/utilities.py b/dice/utilities.py index a9292c8..8a4c295 100644 --- a/dice/utilities.py +++ b/dice/utilities.py @@ -1,8 +1,5 @@ -from __future__ import absolute_import, unicode_literals - import dice.elements from dice.constants import VERBOSE_INDENT -import pyparsing def classname(obj): diff --git a/pyproject.toml b/pyproject.toml index ddb86ed..dcf5719 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,8 +25,6 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", diff --git a/tox.ini b/tox.ini index 19c58e8..81cbf92 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion=1.5.0 -envlist=py37,py38,py39,py310,py311,py312 +envlist=py38,py39,py310,py311,py312 skip_missing_interpreters=true [testenv] From 762cb6c94da1843a12af6fe6a278e0f5aa432061 Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 16:50:58 +0100 Subject: [PATCH 06/11] Format with black --- dice/constants.py | 4 ++-- dice/elements.py | 1 - dice/exceptions.py | 2 +- dice/tests/test_elements.py | 12 ++---------- dice/utilities.py | 2 +- 5 files changed, 6 insertions(+), 15 deletions(-) diff --git a/dice/constants.py b/dice/constants.py index f8b38b9..98142cd 100644 --- a/dice/constants.py +++ b/dice/constants.py @@ -4,6 +4,6 @@ class DiceExtreme: EXTREME_MAX = "MAX" -MAX_ROLL_DICE = 2 ** 20 -MAX_EXPLOSIONS = 2 ** 8 +MAX_ROLL_DICE = 2**20 +MAX_EXPLOSIONS = 2**8 VERBOSE_INDENT = 2 diff --git a/dice/elements.py b/dice/elements.py index 59099be..0bde73d 100644 --- a/dice/elements.py +++ b/dice/elements.py @@ -551,7 +551,6 @@ def function(self, iterable, thresh): class Again(RHSIntegerOperator): def function(self, lhs, rhs=None): - if not isinstance(lhs, IntegerList): lhs = IntegerList([lhs]) diff --git a/dice/exceptions.py b/dice/exceptions.py index 736f808..b68792c 100644 --- a/dice/exceptions.py +++ b/dice/exceptions.py @@ -9,7 +9,7 @@ def from_other(cls, other): elif isinstance(other, ParseFatalException): return DiceFatalException(*other.args) raise NotImplementedError( - 'DiceBaseException can only wrap ParseException or ParseFatalException' + "DiceBaseException can only wrap ParseException or ParseFatalException" ) def pretty_print(self): diff --git a/dice/tests/test_elements.py b/dice/tests/test_elements.py index bf19ee7..02e657c 100644 --- a/dice/tests/test_elements.py +++ b/dice/tests/test_elements.py @@ -137,7 +137,7 @@ def test_roll_error(self): def test_invalid_wrap(self): with raises(NotImplementedError): try: - raise RuntimeError('blah') + raise RuntimeError("blah") except Exception as e: raise DiceException.from_other(e) @@ -200,15 +200,7 @@ def test_sysrandom_roll(self): class TestPickle: - for expr in [ - '-d20', - '4d6t', - '+-(1,2,3)', - '2d20h', - '4d6h3s', - '4dF - 2', - '4*d%' - ]: + for expr in ["-d20", "4d6t", "+-(1,2,3)", "2d20h", "4d6h3s", "4dF - 2", "4*d%"]: value = roll(expr, raw=True, single=False) pickled = pickle.dumps(value) clone = pickle.loads(pickled) diff --git a/dice/utilities.py b/dice/utilities.py index 8a4c295..8dd5b6d 100644 --- a/dice/utilities.py +++ b/dice/utilities.py @@ -22,7 +22,7 @@ def wrap_string(cls, *args, **kwargs): def add_even_sub_odd(operator, operand): - """Add even numbers, subtract odd ones. See http://1w6.org/w6 """ + """Add even numbers, subtract odd ones. See http://1w6.org/w6""" try: for i, x in enumerate(operand): if x % 2: From 4589cba7b07c531c5b4685e9bb85bcd4dd01251b Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 16:51:16 +0100 Subject: [PATCH 07/11] Remove Pipfile, remove coverage, update GitHub Actions workflow --- .github/workflows/tests.yaml | 24 ++- Pipfile | 18 --- Pipfile.lock | 305 ----------------------------------- tox.ini | 26 +-- 4 files changed, 15 insertions(+), 358 deletions(-) delete mode 100644 Pipfile delete mode 100644 Pipfile.lock diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 2120a9b..1a1dfd2 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -6,21 +6,17 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [3.9, 3.8, 3.7, 3.6, 'pypy-3.6', 'pypy-3.7'] + python-version: + - '3.8' + - '3.9' + - '3.10' + - '3.11' + - '3.12' steps: - uses: actions/checkout@v2 - - name: 'Set up Python ${{ matrix.python-version }}' - uses: actions/setup-python@v2 + - uses: actions/setup-python@v2 with: python-version: '${{ matrix.python-version }}' - - name: 'Install Python packaging tools' - run: | - python -m pip install --upgrade pip pipenv - pipenv install --dev - env: - PIPENV_NOSPIN: yes - - name: 'Run pytest' - run: | - pipenv run pytest - env: - PIPENV_NOSPIN: yes + - run: python -m pip install pytest black . + - run: pytest + - run: black --check . diff --git a/Pipfile b/Pipfile deleted file mode 100644 index 8b12b91..0000000 --- a/Pipfile +++ /dev/null @@ -1,18 +0,0 @@ -[[source]] -name = "pypi" -url = "https://pypi.org/simple" -verify_ssl = true - -[dev-packages] -pytest = "*" -pytest-cov = "*" -coverage = "*" -black = "*" -importlib-metadata = "*" - -[packages] -docopt = "*" -pyparsing = "*" - -[pipenv] -allow_prereleases = true diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index d32a25d..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,305 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "4a09050ef40b0a3741bf15bbcffea6f8e168d22bd200334a20a8b3dfae32bf6c" - }, - "pipfile-spec": 6, - "requires": {}, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "docopt": { - "hashes": [ - "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491" - ], - "index": "pypi", - "version": "==0.6.2" - }, - "pyparsing": { - "hashes": [ - "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" - ], - "index": "pypi", - "version": "==2.4.7" - } - }, - "develop": { - "appdirs": { - "hashes": [ - "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", - "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" - ], - "version": "==1.4.4" - }, - "attrs": { - "hashes": [ - "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", - "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.3.0" - }, - "black": { - "hashes": [ - "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea" - ], - "index": "pypi", - "version": "==20.8b1" - }, - "click": { - "hashes": [ - "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", - "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==7.1.2" - }, - "coverage": { - "hashes": [ - "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c", - "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6", - "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45", - "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a", - "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03", - "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529", - "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a", - "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a", - "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2", - "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6", - "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759", - "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53", - "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a", - "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4", - "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff", - "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502", - "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793", - "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb", - "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905", - "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821", - "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b", - "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81", - "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0", - "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b", - "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3", - "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184", - "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701", - "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a", - "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82", - "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638", - "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5", - "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083", - "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6", - "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90", - "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465", - "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a", - "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3", - "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e", - "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066", - "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf", - "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b", - "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae", - "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669", - "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873", - "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b", - "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6", - "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb", - "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160", - "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c", - "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079", - "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d", - "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6" - ], - "index": "pypi", - "version": "==5.5" - }, - "importlib-metadata": { - "hashes": [ - "sha256:c9db46394197244adf2f0b08ec5bc3cf16757e9590b02af1fca085c16c0d600a", - "sha256:d2d46ef77ffc85cbf7dac7e81dd663fde71c45326131bea8033b9bad42268ebe" - ], - "index": "pypi", - "version": "==3.10.0" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "mypy-extensions": { - "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" - ], - "version": "==0.4.3" - }, - "packaging": { - "hashes": [ - "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", - "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.9" - }, - "pathspec": { - "hashes": [ - "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd", - "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d" - ], - "version": "==0.8.1" - }, - "pluggy": { - "hashes": [ - "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", - "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.13.1" - }, - "py": { - "hashes": [ - "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3", - "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.10.0" - }, - "pyparsing": { - "hashes": [ - "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" - ], - "index": "pypi", - "version": "==2.4.7" - }, - "pytest": { - "hashes": [ - "sha256:671238a46e4df0f3498d1c3270e5deb9b32d25134c99b7d75370a68cfbe9b634", - "sha256:6ad9c7bdf517a808242b998ac20063c41532a570d088d77eec1ee12b0b5574bc" - ], - "index": "pypi", - "version": "==6.2.3" - }, - "pytest-cov": { - "hashes": [ - "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7", - "sha256:bdb9fdb0b85a7cc825269a4c56b48ccaa5c7e365054b6038772c32ddcdc969da" - ], - "index": "pypi", - "version": "==2.11.1" - }, - "regex": { - "hashes": [ - "sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5", - "sha256:11d773d75fa650cd36f68d7ca936e3c7afaae41b863b8c387a22aaa78d3c5c79", - "sha256:18c071c3eb09c30a264879f0d310d37fe5d3a3111662438889ae2eb6fc570c31", - "sha256:1e1c20e29358165242928c2de1482fb2cf4ea54a6a6dea2bd7a0e0d8ee321500", - "sha256:281d2fd05555079448537fe108d79eb031b403dac622621c78944c235f3fcf11", - "sha256:314d66636c494ed9c148a42731b3834496cc9a2c4251b1661e40936814542b14", - "sha256:32e65442138b7b76dd8173ffa2cf67356b7bc1768851dded39a7a13bf9223da3", - "sha256:339456e7d8c06dd36a22e451d58ef72cef293112b559010db3d054d5560ef439", - "sha256:3916d08be28a1149fb97f7728fca1f7c15d309a9f9682d89d79db75d5e52091c", - "sha256:3a9cd17e6e5c7eb328517969e0cb0c3d31fd329298dd0c04af99ebf42e904f82", - "sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711", - "sha256:4c46e22a0933dd783467cf32b3516299fb98cfebd895817d685130cc50cd1093", - "sha256:4c557a7b470908b1712fe27fb1ef20772b78079808c87d20a90d051660b1d69a", - "sha256:52ba3d3f9b942c49d7e4bc105bb28551c44065f139a65062ab7912bef10c9afb", - "sha256:563085e55b0d4fb8f746f6a335893bda5c2cef43b2f0258fe1020ab1dd874df8", - "sha256:598585c9f0af8374c28edd609eb291b5726d7cbce16be6a8b95aa074d252ee17", - "sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000", - "sha256:67bdb9702427ceddc6ef3dc382455e90f785af4c13d495f9626861763ee13f9d", - "sha256:6d1b01031dedf2503631d0903cb563743f397ccaf6607a5e3b19a3d76fc10480", - "sha256:741a9647fcf2e45f3a1cf0e24f5e17febf3efe8d4ba1281dcc3aa0459ef424dc", - "sha256:7c2a1af393fcc09e898beba5dd59196edaa3116191cc7257f9224beaed3e1aa0", - "sha256:7d9884d86dd4dd489e981d94a65cd30d6f07203d90e98f6f657f05170f6324c9", - "sha256:90f11ff637fe8798933fb29f5ae1148c978cccb0452005bf4c69e13db951e765", - "sha256:919859aa909429fb5aa9cf8807f6045592c85ef56fdd30a9a3747e513db2536e", - "sha256:96fcd1888ab4d03adfc9303a7b3c0bd78c5412b2bfbe76db5b56d9eae004907a", - "sha256:97f29f57d5b84e73fbaf99ab3e26134e6687348e95ef6b48cfd2c06807005a07", - "sha256:980d7be47c84979d9136328d882f67ec5e50008681d94ecc8afa8a65ed1f4a6f", - "sha256:a91aa8619b23b79bcbeb37abe286f2f408d2f2d6f29a17237afda55bb54e7aac", - "sha256:ade17eb5d643b7fead300a1641e9f45401c98eee23763e9ed66a43f92f20b4a7", - "sha256:b9c3db21af35e3b3c05764461b262d6f05bbca08a71a7849fd79d47ba7bc33ed", - "sha256:bd28bc2e3a772acbb07787c6308e00d9626ff89e3bfcdebe87fa5afbfdedf968", - "sha256:bf5824bfac591ddb2c1f0a5f4ab72da28994548c708d2191e3b87dd207eb3ad7", - "sha256:c0502c0fadef0d23b128605d69b58edb2c681c25d44574fc673b0e52dce71ee2", - "sha256:c38c71df845e2aabb7fb0b920d11a1b5ac8526005e533a8920aea97efb8ec6a4", - "sha256:ce15b6d103daff8e9fee13cf7f0add05245a05d866e73926c358e871221eae87", - "sha256:d3029c340cfbb3ac0a71798100ccc13b97dddf373a4ae56b6a72cf70dfd53bc8", - "sha256:e512d8ef5ad7b898cdb2d8ee1cb09a8339e4f8be706d27eaa180c2f177248a10", - "sha256:e8e5b509d5c2ff12f8418006d5a90e9436766133b564db0abaec92fd27fcee29", - "sha256:ee54ff27bf0afaf4c3b3a62bcd016c12c3fdb4ec4f413391a90bd38bc3624605", - "sha256:fa4537fb4a98fe8fde99626e4681cc644bdcf2a795038533f9f711513a862ae6", - "sha256:fd45ff9293d9274c5008a2054ecef86a9bfe819a67c7be1afb65e69b405b3042" - ], - "version": "==2021.4.4" - }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" - }, - "typed-ast": { - "hashes": [ - "sha256:07d49388d5bf7e863f7fa2f124b1b1d89d8aa0e2f7812faff0a5658c01c59aa1", - "sha256:14bf1522cdee369e8f5581238edac09150c765ec1cb33615855889cf33dcb92d", - "sha256:240296b27397e4e37874abb1df2a608a92df85cf3e2a04d0d4d61055c8305ba6", - "sha256:36d829b31ab67d6fcb30e185ec996e1f72b892255a745d3a82138c97d21ed1cd", - "sha256:37f48d46d733d57cc70fd5f30572d11ab8ed92da6e6b28e024e4a3edfb456e37", - "sha256:4c790331247081ea7c632a76d5b2a265e6d325ecd3179d06e9cf8d46d90dd151", - "sha256:5dcfc2e264bd8a1db8b11a892bd1647154ce03eeba94b461effe68790d8b8e07", - "sha256:7147e2a76c75f0f64c4319886e7639e490fee87c9d25cb1d4faef1d8cf83a440", - "sha256:7703620125e4fb79b64aa52427ec192822e9f45d37d4b6625ab37ef403e1df70", - "sha256:8368f83e93c7156ccd40e49a783a6a6850ca25b556c0fa0240ed0f659d2fe496", - "sha256:84aa6223d71012c68d577c83f4e7db50d11d6b1399a9c779046d75e24bed74ea", - "sha256:85f95aa97a35bdb2f2f7d10ec5bbdac0aeb9dafdaf88e17492da0504de2e6400", - "sha256:8db0e856712f79c45956da0c9a40ca4246abc3485ae0d7ecc86a20f5e4c09abc", - "sha256:9044ef2df88d7f33692ae3f18d3be63dec69c4fb1b5a4a9ac950f9b4ba571606", - "sha256:963c80b583b0661918718b095e02303d8078950b26cc00b5e5ea9ababe0de1fc", - "sha256:987f15737aba2ab5f3928c617ccf1ce412e2e321c77ab16ca5a293e7bbffd581", - "sha256:9ec45db0c766f196ae629e509f059ff05fc3148f9ffd28f3cfe75d4afb485412", - "sha256:9fc0b3cb5d1720e7141d103cf4819aea239f7d136acf9ee4a69b047b7986175a", - "sha256:a2c927c49f2029291fbabd673d51a2180038f8cd5a5b2f290f78c4516be48be2", - "sha256:a38878a223bdd37c9709d07cd357bb79f4c760b29210e14ad0fb395294583787", - "sha256:b4fcdcfa302538f70929eb7b392f536a237cbe2ed9cba88e3bf5027b39f5f77f", - "sha256:c0c74e5579af4b977c8b932f40a5464764b2f86681327410aa028a22d2f54937", - "sha256:c1c876fd795b36126f773db9cbb393f19808edd2637e00fd6caba0e25f2c7b64", - "sha256:c9aadc4924d4b5799112837b226160428524a9a45f830e0d0f184b19e4090487", - "sha256:cc7b98bf58167b7f2db91a4327da24fb93368838eb84a44c472283778fc2446b", - "sha256:cf54cfa843f297991b7388c281cb3855d911137223c6b6d2dd82a47ae5125a41", - "sha256:d003156bb6a59cda9050e983441b7fa2487f7800d76bdc065566b7d728b4581a", - "sha256:d175297e9533d8d37437abc14e8a83cbc68af93cc9c1c59c2c292ec59a0697a3", - "sha256:d746a437cdbca200622385305aedd9aef68e8a645e385cc483bdc5e488f07166", - "sha256:e683e409e5c45d5c9082dc1daf13f6374300806240719f95dc783d1fc942af10" - ], - "version": "==1.4.2" - }, - "typing-extensions": { - "hashes": [ - "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", - "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", - "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" - ], - "version": "==3.7.4.3" - }, - "zipp": { - "hashes": [ - "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76", - "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098" - ], - "markers": "python_version >= '3.6'", - "version": "==3.4.1" - } - } -} diff --git a/tox.ini b/tox.ini index 81cbf92..14d7d5a 100644 --- a/tox.ini +++ b/tox.ini @@ -5,29 +5,13 @@ skip_missing_interpreters=true [testenv] commands=pytest dice -deps= - pytest - pytest-cov - coverage +deps=pytest + +[testenv:black] +commands=black --check --diff . +deps=black [testenv:release] commands=python setup.py sdist bdist_wheel upload skip_sdist=true deps=wheel - -[pytest] -addopts=--tb=short --cov=dice --ignore=setup.py - -[coverage:run] -omit = - dice/tests/conftest.py - dice/__main__.py - -[coverage:report] -exclude_lines= - def __repr__ - raise NotImplementedError - .*# nocover - -[coverage:html] -title=python-dice coverage report From 601f9272ec278fccffdd2aa8cd94d62e4685ffe7 Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 16:52:24 +0100 Subject: [PATCH 08/11] GitHub Actions doesn't support Python 3.12 yet --- .github/workflows/tests.yaml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 1a1dfd2..01ffaac 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -1,7 +1,7 @@ -name: Tests +name: Test on: [push] jobs: - build: + pytest: runs-on: ubuntu-latest strategy: max-parallel: 4 @@ -11,12 +11,11 @@ jobs: - '3.9' - '3.10' - '3.11' - - '3.12' steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - with: - python-version: '${{ matrix.python-version }}' - - run: python -m pip install pytest black . - - run: pytest - - run: black --check . + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: '${{ matrix.python-version }}' + - run: python -m pip install pytest black . + - run: pytest + - run: black --check . From b8be8e1b8594679422c54f4bb1103a17fa5de6da Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 16:56:07 +0100 Subject: [PATCH 09/11] Fix metadata --- dice/__init__.py | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dice/__init__.py b/dice/__init__.py index 55c03e2..f2a8dd2 100644 --- a/dice/__init__.py +++ b/dice/__init__.py @@ -21,8 +21,8 @@ "DiceFatalException", "DiceExtreme", ] -__author__ = "Sam Clements , " "Caleb Johnson " -__version__ = "3.1.2" +__author__ = "Sam Clements , Caleb Johnson " +__version__ = "4.0.0" def roll(string, **kwargs): diff --git a/pyproject.toml b/pyproject.toml index dcf5719..40f77f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "dice" version = "4.0.0" authors = [ { name = "Sam Clements", email = "sam@borntyping.co.uk" }, - { name = "Caleb Johnson" }, + { name = "Caleb Johnson", email = "me@calebj.io" }, ] maintainers = [ { name = "Sam Clements", email = "sam@borntyping.co.uk" }, From 82051f9f7161ec1af388eb54a306e4df5f708da4 Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 17:07:56 +0100 Subject: [PATCH 10/11] Drop docopt --- README.md | 5 ++--- dice/command.py | 47 +++++++++++++++++++++++++---------------------- pyproject.toml | 1 - 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index b7dbfed..328237d 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ The command line arguments are as follows: * `-V` `--version` Show the package version If your expression begins with a dash (`-`), then put a double dash (`--`) -before it to prevent docopt from trying to process it as a command option. +before it to prevent the parser from trying to process it as a command option. Example: `roll -- -10d6`. Alternatively, use parenthesis: `roll (-10d6)`. ### Python API @@ -49,8 +49,7 @@ command-line tool, I recommend [pipx]. A recent version of Python 3 (3.8 or above) is required. You can probably run it or easily adapt it for older versions of Python, but I don't support any -end-of-life Python versions. Beyond that, the only dependencies are the -`docopt` and `pyparsing` libraries. +end-of-life Python versions. Beyond that, the only dependency is the `pyparsing` library. [pipx]: https://pypa.github.io/pipx/ diff --git a/dice/command.py b/dice/command.py index 136540b..37b0b38 100644 --- a/dice/command.py +++ b/dice/command.py @@ -11,48 +11,51 @@ -V --version Show the package version """ -import docopt +import argparse import dice -from dice.exceptions import DiceBaseException +import dice.exceptions -__version__ = "dice v{0} by {1}".format(dice.__version__, dice.__author__) +__version__ = "dice v{0} by {1}.".format(dice.__version__, dice.__author__) +parser = argparse.ArgumentParser(prog="dice", description="Parse and evaluate dice notation.", epilog=__version__) +parser.add_argument('-m', '--min', action="store_true", help="Make all rolls the lowest possible result.") +parser.add_argument('-M', '--max', action="store_true", help="Make all rolls the highest possible result.") +parser.add_argument('-D', '--max-dice', action="store", type=int, metavar='N', help="Set the maximum number of dice per element.") +parser.add_argument('-v', '--verbose', action="store_true", help="Show additional output.") +parser.add_argument('-V', '--version', action="version", version=__version__, help="Show the package version.") +parser.add_argument('expression', nargs='+') -def main(argv=None): - """Run roll() from a command line interface""" - args = docopt.docopt(__doc__, argv=argv, version=__version__) - verbose = bool(args["--verbose"]) - f_roll = dice.roll - kwargs = {} +def main(args=None): + """Run roll() from a command line interface""" + args = parser.parse_args(args=args) + f_kwargs = {} - if args["--min"]: + if args.min: f_roll = dice.roll_min - elif args["--max"]: + elif args.max: f_roll = dice.roll_max + else: + f_roll = dice.roll - if args["--max-dice"]: - try: - kwargs["max_dice"] = int(args["--max-dice"]) - except ValueError: - print("Invalid value for --max-dice: '%s'" % args["--max-dice"]) - exit(1) + if args.max_dice: + f_kwargs['max_dice'] = args.max_dice - expr = " ".join(args[""]) + f_expr = " ".join(args.expression) try: - roll, kwargs = f_roll(expr, raw=True, return_kwargs=True, **kwargs) + roll, kwargs = f_roll(f_expr, raw=True, return_kwargs=True, **f_kwargs) - if verbose: + if args.verbose: print("Result: ", end="") print(str(roll.evaluate_cached(**kwargs))) - if verbose: + if args.verbose: print("Breakdown:") print(dice.utilities.verbose_print(roll, **kwargs)) - except DiceBaseException as e: + except dice.exceptions.DiceBaseException as e: print("Whoops! Something went wrong:") print(e.pretty_print()) exit(1) diff --git a/pyproject.toml b/pyproject.toml index 40f77f5..d0001d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,6 @@ classifiers = [ ] keywords = ["dice"] dependencies = [ - "docopt>=0.6.1", "pyparsing>=2.4.1", ] urls = { homepage = "https://github.com/borntyping/python-dice" } From 20183f1be2403b2b58e03a1287b0651e5f48afd3 Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 18 May 2023 18:15:25 +0100 Subject: [PATCH 11/11] Reformat code --- dice/command.py | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/dice/command.py b/dice/command.py index 37b0b38..0af659c 100644 --- a/dice/command.py +++ b/dice/command.py @@ -18,13 +18,44 @@ __version__ = "dice v{0} by {1}.".format(dice.__version__, dice.__author__) -parser = argparse.ArgumentParser(prog="dice", description="Parse and evaluate dice notation.", epilog=__version__) -parser.add_argument('-m', '--min', action="store_true", help="Make all rolls the lowest possible result.") -parser.add_argument('-M', '--max', action="store_true", help="Make all rolls the highest possible result.") -parser.add_argument('-D', '--max-dice', action="store", type=int, metavar='N', help="Set the maximum number of dice per element.") -parser.add_argument('-v', '--verbose', action="store_true", help="Show additional output.") -parser.add_argument('-V', '--version', action="version", version=__version__, help="Show the package version.") -parser.add_argument('expression', nargs='+') +parser = argparse.ArgumentParser( + prog="dice", description="Parse and evaluate dice notation.", epilog=__version__ +) +parser.add_argument( + "-m", + "--min", + action="store_true", + help="Make all rolls the lowest possible result.", +) +parser.add_argument( + "-M", + "--max", + action="store_true", + help="Make all rolls the highest possible result.", +) +parser.add_argument( + "-D", + "--max-dice", + action="store", + type=int, + metavar="N", + help="Set the maximum number of dice per element.", +) +parser.add_argument( + "-v", "--verbose", action="store_true", help="Show additional output." +) +parser.add_argument( + "-V", + "--version", + action="version", + version=__version__, + help="Show the package version.", +) +parser.add_argument( + "expression", + nargs="+", + help="One or more expressions in dice notation", +) def main(args=None): @@ -40,7 +71,7 @@ def main(args=None): f_roll = dice.roll if args.max_dice: - f_kwargs['max_dice'] = args.max_dice + f_kwargs["max_dice"] = args.max_dice f_expr = " ".join(args.expression)