mirror of
				https://github.com/enpaul/tox-poetry-installer.git
				synced 2025-10-29 07:10:09 +00:00 
			
		
		
		
	Compare commits
	
		
			40 Commits
		
	
	
		
			0.8.3
			...
			779dd8c56f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 779dd8c56f | |||
| 3399bbecc2 | |||
| dd61f8c40f | |||
| 447475ebe0 | |||
| d711a17596 | |||
| 4f69c8b3b2 | |||
| bd102605b6 | |||
| 469cb251cf | |||
| 41ac5423f9 | |||
| 3388553ee0 | |||
| 52f34cb317 | |||
| 4c609770f1 | |||
| d5650f0562 | |||
| 4261d45218 | |||
| d0842456cb | |||
| b631a962b2 | |||
| 453b575159 | |||
| 50e1aaddcd | |||
|  | d0efbd06b3 | ||
| c435f1af69 | |||
| 817ae28a23 | |||
| 12c4ec62f2 | |||
|  | 73ddd43284 | ||
|  | a181da95b3 | ||
|  | e8ce2f391b | ||
|  | c8fd6e4fc0 | ||
|  | 22012d4452 | ||
|  | 17d0272089 | ||
|  | b54bf44dc5 | ||
| 17885b50f7 | |||
| 72c719c26c | |||
| 5f30656683 | |||
| b3a5e869ac | |||
| afc94a5e01 | |||
| a9d29aea9f | |||
| 45e33b7d27 | |||
| ff3e1603d2 | |||
| fb65fa812e | |||
| f08a18728e | |||
| 07027181ce | 
							
								
								
									
										2
									
								
								.github/scripts/setup-env.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/scripts/setup-env.sh
									
									
									
									
										vendored
									
									
								
							| @@ -8,7 +8,7 @@ | |||||||
| set -e; | set -e; | ||||||
|  |  | ||||||
| CI_CACHE=$HOME/.cache; | CI_CACHE=$HOME/.cache; | ||||||
| POETRY_VERSION=1.1.12; | POETRY_VERSION=1.3.2; | ||||||
|  |  | ||||||
| mkdir --parents "$CI_CACHE"; | mkdir --parents "$CI_CACHE"; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								.github/workflows/ci.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.github/workflows/ci.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -7,12 +7,11 @@ on: | |||||||
|     branches: ["devel"] |     branches: ["devel"] | ||||||
| jobs: | jobs: | ||||||
|   Test: |   Test: | ||||||
|  |     name: Python ${{ matrix.python.version }} | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     strategy: |     strategy: | ||||||
|       matrix: |       matrix: | ||||||
|         python: |         python: | ||||||
|           - version: "3.6" |  | ||||||
|             toxenv: py36 |  | ||||||
|           - version: "3.7" |           - version: "3.7" | ||||||
|             toxenv: py37 |             toxenv: py37 | ||||||
|           - version: "3.8" |           - version: "3.8" | ||||||
| @@ -21,15 +20,20 @@ jobs: | |||||||
|             toxenv: py39 |             toxenv: py39 | ||||||
|           - version: "3.10" |           - version: "3.10" | ||||||
|             toxenv: py310 |             toxenv: py310 | ||||||
|  |           - version: "3.11" | ||||||
|  |             toxenv: py311 | ||||||
|  |       fail-fast: true | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout |       - name: Checkout | ||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v2 | ||||||
|  |  | ||||||
|       - name: Install Python ${{ matrix.python.version }} |       - name: Install Python ${{ matrix.python.version }} | ||||||
|         uses: actions/setup-python@v1 |         uses: actions/setup-python@v4 | ||||||
|         with: |         with: | ||||||
|           python-version: ${{ matrix.python.version }} |           python-version: ${{ matrix.python.version }} | ||||||
|  |  | ||||||
|       - name: Configure Job Cache |       - name: Configure Job Cache | ||||||
|         uses: actions/cache@v2 |         uses: actions/cache@v3 | ||||||
|         with: |         with: | ||||||
|           path: | |           path: | | ||||||
|             ~/.cache/pip |             ~/.cache/pip | ||||||
| @@ -39,38 +43,49 @@ jobs: | |||||||
|           # will be invalidated, and thus all packages will be redownloaded, if the |           # will be invalidated, and thus all packages will be redownloaded, if the | ||||||
|           # lockfile is updated |           # lockfile is updated | ||||||
|           key: ${{ runner.os }}-${{ matrix.python.toxenv }}-${{ hashFiles('**/poetry.lock') }} |           key: ${{ runner.os }}-${{ matrix.python.toxenv }}-${{ hashFiles('**/poetry.lock') }} | ||||||
|  |  | ||||||
|       - name: Configure Path |       - name: Configure Path | ||||||
|         run: echo "$HOME/.local/bin" >> $GITHUB_PATH |         run: echo "$HOME/.local/bin" >> $GITHUB_PATH | ||||||
|  |  | ||||||
|       - name: Configure Environment |       - name: Configure Environment | ||||||
|         run: .github/scripts/setup-env.sh |         run: .github/scripts/setup-env.sh | ||||||
|  |  | ||||||
|       - name: Run Toxenv ${{ matrix.python.toxenv }} |       - name: Run Toxenv ${{ matrix.python.toxenv }} | ||||||
|         run: poetry run tox -e ${{ matrix.python.toxenv }} |         run: poetry run tox -e ${{ matrix.python.toxenv }} | ||||||
|  |  | ||||||
|   Check: |   Check: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout |       - name: Checkout | ||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v2 | ||||||
|       - name: Install Python 3.8 |  | ||||||
|         uses: actions/setup-python@v1 |       - name: Install Python 3.10 | ||||||
|  |         uses: actions/setup-python@v4 | ||||||
|         with: |         with: | ||||||
|           python-version: 3.8 |           python-version: "3.10" | ||||||
|  |  | ||||||
|       - name: Configure Job Cache |       - name: Configure Job Cache | ||||||
|         uses: actions/cache@v2 |         uses: actions/cache@v3 | ||||||
|         with: |         with: | ||||||
|           path: | |           path: | | ||||||
|             ~/.cache/pip |             ~/.cache/pip | ||||||
|             ~/.cache/pypoetry/cache |             ~/.cache/pypoetry/cache | ||||||
|             ~/.poetry |             ~/.poetry | ||||||
|           # Hardcoded 'py38' slug here lets this cache piggyback on the 'py38' cache |           # Hardcoded 'py310' slug here lets this cache piggyback on the 'py310' cache | ||||||
|           # that is generated for the tests above |           # that is generated for the tests above | ||||||
|           key: ${{ runner.os }}-py38-${{ hashFiles('**/poetry.lock') }} |           key: ${{ runner.os }}-py310-${{ hashFiles('**/poetry.lock') }} | ||||||
|  |  | ||||||
|       - name: Configure Path |       - name: Configure Path | ||||||
|         run: echo "$HOME/.local/bin" >> $GITHUB_PATH |         run: echo "$HOME/.local/bin" >> $GITHUB_PATH | ||||||
|  |  | ||||||
|       - name: Configure Environment |       - name: Configure Environment | ||||||
|         run: .github/scripts/setup-env.sh |         run: .github/scripts/setup-env.sh | ||||||
|  |  | ||||||
|       - name: Run Static Analysis Checks |       - name: Run Static Analysis Checks | ||||||
|         run: poetry run tox -e static |         run: poetry run tox -e static | ||||||
|  |  | ||||||
|       - name: Run Static Analysis Checks (Tests) |       - name: Run Static Analysis Checks (Tests) | ||||||
|         run: poetry run tox -e static-tests |         run: poetry run tox -e static-tests | ||||||
|  |  | ||||||
|       - name: Run Security Checks |       - name: Run Security Checks | ||||||
|         run: poetry run tox -e security |         run: poetry run tox -e security | ||||||
|   | |||||||
							
								
								
									
										400
									
								
								.pylintrc
									
									
									
									
									
								
							
							
						
						
									
										400
									
								
								.pylintrc
									
									
									
									
									
								
							| @@ -1,46 +1,5 @@ | |||||||
| [MASTER] |  | ||||||
|  |  | ||||||
| # A comma-separated list of package or module names from where C extensions may |  | ||||||
| # be loaded. Extensions are loading into the active Python interpreter and may |  | ||||||
| # run arbitrary code |  | ||||||
| extension-pkg-whitelist= |  | ||||||
|  |  | ||||||
| # Add files or directories to the blacklist. They should be base names, not |  | ||||||
| # paths. |  | ||||||
| ignore= |  | ||||||
|  |  | ||||||
| # Add files or directories matching the regex patterns to the blacklist. The |  | ||||||
| # regex matches against base names, not paths. |  | ||||||
| ignore-patterns= |  | ||||||
|  |  | ||||||
| # Python code to execute, usually for sys.path manipulation such as |  | ||||||
| # pygtk.require(). |  | ||||||
| #init-hook= |  | ||||||
|  |  | ||||||
| # Use multiple processes to speed up Pylint. |  | ||||||
| jobs=1 |  | ||||||
|  |  | ||||||
| # List of plugins (as comma separated values of python modules names) to load, |  | ||||||
| # usually to register additional checkers. |  | ||||||
| load-plugins= |  | ||||||
|  |  | ||||||
| # Pickle collected data for later comparisons. |  | ||||||
| persistent=yes |  | ||||||
|  |  | ||||||
| # Specify a configuration file. |  | ||||||
| #rcfile= |  | ||||||
|  |  | ||||||
| # Allow loading of arbitrary C extensions. Extensions are imported into the |  | ||||||
| # active Python interpreter and may run arbitrary code. |  | ||||||
| unsafe-load-any-extension=no |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [MESSAGES CONTROL] | [MESSAGES CONTROL] | ||||||
|  |  | ||||||
| # Only show warnings with the listed confidence levels. Leave empty to show |  | ||||||
| # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED |  | ||||||
| confidence= |  | ||||||
|  |  | ||||||
| # Disable the message, report, category or checker with the given id(s). You | # Disable the message, report, category or checker with the given id(s). You | ||||||
| # can either give multiple identifiers separated by comma (,) or put this | # can either give multiple identifiers separated by comma (,) or put this | ||||||
| # option multiple times (only on the command line, not in the configuration | # option multiple times (only on the command line, not in the configuration | ||||||
| @@ -50,378 +9,47 @@ confidence= | |||||||
| # --enable=similarities". If you want to run only the classes checker, but have | # --enable=similarities". If you want to run only the classes checker, but have | ||||||
| # no Warning level messages displayed, use"--disable=all --enable=classes | # no Warning level messages displayed, use"--disable=all --enable=classes | ||||||
| # --disable=W" | # --disable=W" | ||||||
| disable=logging-fstring-interpolation, logging-format-interpolation, bad-continuation, line-too-long | disable=logging-fstring-interpolation | ||||||
| #print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call, |         ,logging-format-interpolation | ||||||
|  |         ,bad-continuation | ||||||
| # Enable the message, report, category or checker with the given id(s). You can |         ,line-too-long | ||||||
| # either give multiple identifier separated by comma (,) or put this option |         ,ungrouped-imports | ||||||
| # multiple time (only on the command line, not in the configuration file where |         ,typecheck | ||||||
| # it should appear only once). See also the "--disable" option for examples. |         ,wrong-import-order | ||||||
| enable= |         ,wrong-import-position | ||||||
|  |  | ||||||
|  |  | ||||||
| [REPORTS] | [REPORTS] | ||||||
|  |  | ||||||
| # Python expression which should return a note less than 10 (10 is the highest |  | ||||||
| # note). You have access to the variables errors warning, statement which |  | ||||||
| # respectively contain the number of errors / warnings messages and the total |  | ||||||
| # number of statements analyzed. This is used by the global evaluation report |  | ||||||
| # (RP0004). |  | ||||||
| evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) |  | ||||||
|  |  | ||||||
| # Template used to display messages. This is a python new-style format string |  | ||||||
| # used to format the message information. See doc for all details |  | ||||||
| #msg-template= |  | ||||||
|  |  | ||||||
| # Set the output format. Available formats are text, parseable, colorized, json | # Set the output format. Available formats are text, parseable, colorized, json | ||||||
| # and msvs (visual studio).You can also give a reporter class, eg | # and msvs (visual studio).You can also give a reporter class, eg | ||||||
| # mypackage.mymodule.MyReporterClass. | # mypackage.mymodule.MyReporterClass. | ||||||
| output-format=text | output-format=colorized | ||||||
|  |  | ||||||
| # Tells whether to display a full report or only the messages |  | ||||||
| reports=no |  | ||||||
|  |  | ||||||
| # Activate the evaluation score. |  | ||||||
| score=yes |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [REFACTORING] |  | ||||||
|  |  | ||||||
| # Maximum number of nested blocks for function / method body |  | ||||||
| max-nested-blocks=5 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [BASIC] | [BASIC] | ||||||
|  |  | ||||||
| # Naming hint for argument names |  | ||||||
| argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ |  | ||||||
|  |  | ||||||
| # Regular expression matching correct argument names |  | ||||||
| argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ |  | ||||||
|  |  | ||||||
| # Naming hint for attribute names |  | ||||||
| attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ |  | ||||||
|  |  | ||||||
| # Regular expression matching correct attribute names |  | ||||||
| attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ |  | ||||||
|  |  | ||||||
| # Bad variable names which should always be refused, separated by a comma |  | ||||||
| bad-names=foo,bar,baz,toto,tutu,tata |  | ||||||
|  |  | ||||||
| # Naming hint for class attribute names |  | ||||||
| class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ |  | ||||||
|  |  | ||||||
| # Regular expression matching correct class attribute names |  | ||||||
| class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ |  | ||||||
|  |  | ||||||
| # Naming hint for class names |  | ||||||
| class-name-hint=[A-Z_][a-zA-Z0-9]+$ |  | ||||||
|  |  | ||||||
| # Regular expression matching correct class names |  | ||||||
| class-rgx=[A-Z_][a-zA-Z0-9]+$ |  | ||||||
|  |  | ||||||
| # Naming hint for constant names |  | ||||||
| const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ |  | ||||||
|  |  | ||||||
| # Regular expression matching correct constant names |  | ||||||
| const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ |  | ||||||
|  |  | ||||||
| # Minimum line length for functions/classes that require docstrings, shorter |  | ||||||
| # ones are exempt. |  | ||||||
| docstring-min-length=-1 |  | ||||||
|  |  | ||||||
| # Naming hint for function names |  | ||||||
| function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ |  | ||||||
|  |  | ||||||
| # Regular expression matching correct function names |  | ||||||
| function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ |  | ||||||
|  |  | ||||||
| # Good variable names which should always be accepted, separated by a comma | # Good variable names which should always be accepted, separated by a comma | ||||||
| good-names=_,ip,ap | good-names=_,ip,T | ||||||
|  |  | ||||||
| # Include a hint for the correct naming format with invalid-name |  | ||||||
| include-naming-hint=no |  | ||||||
|  |  | ||||||
| # Naming hint for inline iteration names |  | ||||||
| inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ |  | ||||||
|  |  | ||||||
| # Regular expression matching correct inline iteration names |  | ||||||
| inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ |  | ||||||
|  |  | ||||||
| # Naming hint for method names |  | ||||||
| method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ |  | ||||||
|  |  | ||||||
| # Regular expression matching correct method names |  | ||||||
| method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ |  | ||||||
|  |  | ||||||
| # Naming hint for module names |  | ||||||
| module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ |  | ||||||
|  |  | ||||||
| # Regular expression matching correct module names |  | ||||||
| module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ |  | ||||||
|  |  | ||||||
| # Colon-delimited sets of names that determine each other's naming style when |  | ||||||
| # the name regexes allow several styles. |  | ||||||
| name-group= |  | ||||||
|  |  | ||||||
| # Regular expression which should only match function or class names that do |  | ||||||
| # not require a docstring. |  | ||||||
| no-docstring-rgx=^_ |  | ||||||
|  |  | ||||||
| # List of decorators that produce properties, such as abc.abstractproperty. Add |  | ||||||
| # to this list to register other decorators that produce valid properties. |  | ||||||
| property-classes=abc.abstractproperty |  | ||||||
|  |  | ||||||
| # Naming hint for variable names |  | ||||||
| variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ |  | ||||||
|  |  | ||||||
| # Regular expression matching correct variable names |  | ||||||
| variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [MISCELLANEOUS] | [MISCELLANEOUS] | ||||||
|  | # Not FIXME or TODO | ||||||
| # List of note tags to take in consideration, separated by a comma. |  | ||||||
| #notes=FIXME,XXX,TODO |  | ||||||
| notes=XXX | notes=XXX | ||||||
|  |  | ||||||
|  |  | ||||||
| [LOGGING] |  | ||||||
|  |  | ||||||
| # Logging modules to check that the string format arguments are in logging |  | ||||||
| # function parameter format |  | ||||||
| logging-modules=logging |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [SIMILARITIES] | [SIMILARITIES] | ||||||
|  |  | ||||||
| # Ignore comments when computing similarities. |  | ||||||
| ignore-comments=yes |  | ||||||
|  |  | ||||||
| # Ignore docstrings when computing similarities. |  | ||||||
| ignore-docstrings=yes |  | ||||||
|  |  | ||||||
| # Ignore imports when computing similarities. | # Ignore imports when computing similarities. | ||||||
| ignore-imports=yes | ignore-imports=yes | ||||||
|  |  | ||||||
|  | # Ignore function signatures when computing similarities. | ||||||
|  | ignore-signatures=yes | ||||||
|  |  | ||||||
| # Minimum lines number of a similarity. | # Minimum lines number of a similarity. | ||||||
| min-similarity-lines=10 | min-similarity-lines=10 | ||||||
|  |  | ||||||
|  |  | ||||||
| [VARIABLES] |  | ||||||
|  |  | ||||||
| # List of additional names supposed to be defined in builtins. Remember that |  | ||||||
| # you should avoid to define new builtins when possible. |  | ||||||
| additional-builtins= |  | ||||||
|  |  | ||||||
| # Tells whether unused global variables should be treated as a violation. |  | ||||||
| allow-global-unused-variables=yes |  | ||||||
|  |  | ||||||
| # List of strings which can identify a callback function by name. A callback |  | ||||||
| # name must start or end with one of those strings. |  | ||||||
| callbacks=cb_,_cb |  | ||||||
|  |  | ||||||
| # A regular expression matching the name of dummy variables (i.e. expectedly |  | ||||||
| # not used). |  | ||||||
| dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ |  | ||||||
|  |  | ||||||
| # Argument names that match this expression will be ignored. Default to name |  | ||||||
| # with leading underscore |  | ||||||
| ignored-argument-names=_.*|^ignored_|^unused_|^fxt_ |  | ||||||
|  |  | ||||||
| # Tells whether we should check for unused import in __init__ files. |  | ||||||
| init-import=no |  | ||||||
|  |  | ||||||
| # List of qualified module names which can have objects that can redefine |  | ||||||
| # builtins. |  | ||||||
| redefining-builtins-modules=six.moves,future.builtins |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [SPELLING] |  | ||||||
|  |  | ||||||
| # Spelling dictionary name. Available dictionaries: none. To make it working |  | ||||||
| # install python-enchant package. |  | ||||||
| spelling-dict= |  | ||||||
|  |  | ||||||
| # List of comma separated words that should not be checked. |  | ||||||
| spelling-ignore-words= |  | ||||||
|  |  | ||||||
| # A path to a file that contains private dictionary; one word per line. |  | ||||||
| spelling-private-dict-file= |  | ||||||
|  |  | ||||||
| # Tells whether to store unknown words to indicated private dictionary in |  | ||||||
| # --spelling-private-dict-file option instead of raising a message. |  | ||||||
| spelling-store-unknown-words=no |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [FORMAT] |  | ||||||
|  |  | ||||||
| # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. |  | ||||||
| expected-line-ending-format= |  | ||||||
|  |  | ||||||
| # Regexp for a line that is allowed to be longer than the limit. |  | ||||||
| ignore-long-lines=^\s*(# )?<?https?://\S+>?$ |  | ||||||
|  |  | ||||||
| # Number of spaces of indent required inside a hanging  or continued line. |  | ||||||
| indent-after-paren=4 |  | ||||||
|  |  | ||||||
| # String used as indentation unit. This is usually "    " (4 spaces) or "\t" (1 |  | ||||||
| # tab). |  | ||||||
| indent-string='    ' |  | ||||||
|  |  | ||||||
| # Maximum number of characters on a single line. |  | ||||||
| max-line-length=100 |  | ||||||
|  |  | ||||||
| # Maximum number of lines in a module |  | ||||||
| max-module-lines=1000 |  | ||||||
|  |  | ||||||
| # List of optional constructs for which whitespace checking is disabled. `dict- |  | ||||||
| # separator` is used to allow tabulation in dicts, etc.: {1  : 1,\n222: 2}. |  | ||||||
| # `trailing-comma` allows a space between comma and closing bracket: (a, ). |  | ||||||
| # `empty-line` allows space-only lines. |  | ||||||
| no-space-check=trailing-comma,dict-separator |  | ||||||
|  |  | ||||||
| # Allow the body of a class to be on the same line as the declaration if body |  | ||||||
| # contains single statement. |  | ||||||
| single-line-class-stmt=no |  | ||||||
|  |  | ||||||
| # Allow the body of an if to be on the same line as the test if there is no |  | ||||||
| # else. |  | ||||||
| single-line-if-stmt=no |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [TYPECHECK] |  | ||||||
|  |  | ||||||
| # List of decorators that produce context managers, such as |  | ||||||
| # contextlib.contextmanager. Add to this list to register other decorators that |  | ||||||
| # produce valid context managers. |  | ||||||
| contextmanager-decorators=contextlib.contextmanager |  | ||||||
|  |  | ||||||
| # List of members which are set dynamically and missed by pylint inference |  | ||||||
| # system, and so shouldn't trigger E1101 when accessed. Python regular |  | ||||||
| # expressions are accepted. |  | ||||||
| generated-members= |  | ||||||
|  |  | ||||||
| # Tells whether missing members accessed in mixin class should be ignored. A |  | ||||||
| # mixin class is detected if its name ends with "mixin" (case insensitive). |  | ||||||
| ignore-mixin-members=yes |  | ||||||
|  |  | ||||||
| # This flag controls whether pylint should warn about no-member and similar |  | ||||||
| # checks whenever an opaque object is returned when inferring. The inference |  | ||||||
| # can return multiple potential results while evaluating a Python object, but |  | ||||||
| # some branches might not be evaluated, which results in partial inference. In |  | ||||||
| # that case, it might be useful to still emit no-member and other checks for |  | ||||||
| # the rest of the inferred objects. |  | ||||||
| ignore-on-opaque-inference=yes |  | ||||||
|  |  | ||||||
| # List of class names for which member attributes should not be checked (useful |  | ||||||
| # for classes with dynamically set attributes). This supports the use of |  | ||||||
| # qualified names. |  | ||||||
| ignored-classes=optparse.Values,thread._local,_thread._local |  | ||||||
|  |  | ||||||
| # List of module names for which member attributes should not be checked |  | ||||||
| # (useful for modules/projects where namespaces are manipulated during runtime |  | ||||||
| # and thus existing member attributes cannot be deduced by static analysis. It |  | ||||||
| # supports qualified module names, as well as Unix pattern matching. |  | ||||||
| ignored-modules= |  | ||||||
|  |  | ||||||
| # Show a hint with possible names when a member name was not found. The aspect |  | ||||||
| # of finding the hint is based on edit distance. |  | ||||||
| missing-member-hint=yes |  | ||||||
|  |  | ||||||
| # The minimum edit distance a name should have in order to be considered a |  | ||||||
| # similar match for a missing member name. |  | ||||||
| missing-member-hint-distance=1 |  | ||||||
|  |  | ||||||
| # The total number of similar names that should be taken in consideration when |  | ||||||
| # showing a hint for a missing member. |  | ||||||
| missing-member-max-choices=1 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [CLASSES] |  | ||||||
|  |  | ||||||
| # List of method names used to declare (i.e. assign) instance attributes. |  | ||||||
| defining-attr-methods=__init__,__new__,setUp |  | ||||||
|  |  | ||||||
| # List of member names, which should be excluded from the protected access |  | ||||||
| # warning. |  | ||||||
| exclude-protected=_asdict,_fields,_replace,_source,_make |  | ||||||
|  |  | ||||||
| # List of valid names for the first argument in a class method. |  | ||||||
| valid-classmethod-first-arg=cls |  | ||||||
|  |  | ||||||
| # List of valid names for the first argument in a metaclass class method. |  | ||||||
| valid-metaclass-classmethod-first-arg=mcs |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [IMPORTS] |  | ||||||
|  |  | ||||||
| # Allow wildcard imports from modules that define __all__. |  | ||||||
| allow-wildcard-with-all=no |  | ||||||
|  |  | ||||||
| # Analyse import fallback blocks. This can be used to support both Python 2 and |  | ||||||
| # 3 compatible code, which means that the block might have code that exists |  | ||||||
| # only in one or another interpreter, leading to false positives when analysed. |  | ||||||
| analyse-fallback-blocks=no |  | ||||||
|  |  | ||||||
| # Deprecated modules which should not be used, separated by a comma |  | ||||||
| deprecated-modules=regsub,TERMIOS,Bastion,rexec |  | ||||||
|  |  | ||||||
| # Create a graph of external dependencies in the given file (report RP0402 must |  | ||||||
| # not be disabled) |  | ||||||
| ext-import-graph= |  | ||||||
|  |  | ||||||
| # Create a graph of every (i.e. internal and external) dependencies in the |  | ||||||
| # given file (report RP0402 must not be disabled) |  | ||||||
| import-graph= |  | ||||||
|  |  | ||||||
| # Create a graph of internal dependencies in the given file (report RP0402 must |  | ||||||
| # not be disabled) |  | ||||||
| int-import-graph= |  | ||||||
|  |  | ||||||
| # Force import order to recognize a module as part of the standard |  | ||||||
| # compatibility libraries. |  | ||||||
| known-standard-library= |  | ||||||
|  |  | ||||||
| # Force import order to recognize a module as part of a third party library. |  | ||||||
| known-third-party=enchant |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [DESIGN] | [DESIGN] | ||||||
|  |  | ||||||
| # Maximum number of arguments for function / method | # Maximum number of arguments for function / method | ||||||
| max-args=7 | max-args=7 | ||||||
|  |  | ||||||
| # Maximum number of attributes for a class (see R0902). |  | ||||||
| max-attributes=7 |  | ||||||
|  |  | ||||||
| # Maximum number of boolean expressions in a if statement |  | ||||||
| max-bool-expr=5 |  | ||||||
|  |  | ||||||
| # Maximum number of branch for function / method body |  | ||||||
| max-branches=12 |  | ||||||
|  |  | ||||||
| # Maximum number of locals for function / method body |  | ||||||
| max-locals=15 |  | ||||||
|  |  | ||||||
| # Maximum number of parents for a class (see R0901). |  | ||||||
| max-parents=7 |  | ||||||
|  |  | ||||||
| # Maximum number of public methods for a class (see R0904). |  | ||||||
| max-public-methods=20 |  | ||||||
|  |  | ||||||
| # Maximum number of return / yield for function / method body |  | ||||||
| max-returns=6 |  | ||||||
|  |  | ||||||
| # Maximum number of statements in function / method body |  | ||||||
| max-statements=50 |  | ||||||
|  |  | ||||||
| # Minimum number of public methods for a class (see R0903). |  | ||||||
| min-public-methods=2 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [EXCEPTIONS] |  | ||||||
|  |  | ||||||
| # Exceptions that will emit a warning when being caught. Defaults to |  | ||||||
| # "Exception" |  | ||||||
| overgeneral-exceptions=Exception |  | ||||||
|   | |||||||
							
								
								
									
										53
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -2,6 +2,57 @@ | |||||||
|  |  | ||||||
| See also: [Github Release Page](https://github.com/enpaul/tox-poetry-installer/releases). | See also: [Github Release Page](https://github.com/enpaul/tox-poetry-installer/releases). | ||||||
|  |  | ||||||
|  | ## Version 0.10.1 | ||||||
|  |  | ||||||
|  | View this release on: | ||||||
|  | [Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.10.1), | ||||||
|  | [PyPI](https://pypi.org/project/tox-poetry-installer/0.10.1/) | ||||||
|  |  | ||||||
|  | - Add PyPI classifier for Python-3.11 compatibility | ||||||
|  | - Add CI support for Python-3.11 | ||||||
|  | - Add support for Poetry-1.3.x (#83) | ||||||
|  |  | ||||||
|  | ## Version 0.10.0 | ||||||
|  |  | ||||||
|  | View this release on: | ||||||
|  | [Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.10.0), | ||||||
|  | [PyPI](https://pypi.org/project/tox-poetry-installer/0.10.0/) | ||||||
|  |  | ||||||
|  | - Add `poetry_dep_groups` option to support installing groups of Poetry dependencies. | ||||||
|  |   Contributed by [Oshmoun](https://github.com/oshmoun) (#76) | ||||||
|  | - Deprecate `install_dev_deps` option | ||||||
|  |  | ||||||
|  | ## Version 0.9.0 | ||||||
|  |  | ||||||
|  | View this release on: | ||||||
|  | [Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.9.0), | ||||||
|  | [PyPI](https://pypi.org/project/tox-poetry-installer/0.9.0/) | ||||||
|  |  | ||||||
|  | - Add support for Poetry-1.2.x. Contributed by [Justin Wood](https://github.com/Callek) | ||||||
|  |   (#73) | ||||||
|  | - Update Black formatting to stable release version | ||||||
|  | - Remove support for Python-3.6 | ||||||
|  | - Remove support for Poetry-1.1.x | ||||||
|  | - Fix installing dependencies multiple times when transient dependencies are duplicated in | ||||||
|  |   the dependency tree | ||||||
|  |  | ||||||
|  | ## Version 0.8.5 | ||||||
|  |  | ||||||
|  | View this release on: | ||||||
|  | [Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.8.5), | ||||||
|  | [PyPI](https://pypi.org/project/tox-poetry-installer/0.8.5/) | ||||||
|  |  | ||||||
|  | - Fix Poetry version specification supporting the incompatible Poetry-1.2.0 release | ||||||
|  |  | ||||||
|  | ## Version 0.8.4 | ||||||
|  |  | ||||||
|  | View this release on: | ||||||
|  | [Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.8.4), | ||||||
|  | [PyPI](https://pypi.org/project/tox-poetry-installer/0.8.4/) | ||||||
|  |  | ||||||
|  | - Fix issue where incompatible package versions were selected for installation when multiple | ||||||
|  |   package versions were in the lockfile | ||||||
|  |  | ||||||
| ## Version 0.8.3 | ## Version 0.8.3 | ||||||
|  |  | ||||||
| View this release on: | View this release on: | ||||||
| @@ -18,7 +69,7 @@ View this release on: | |||||||
|  |  | ||||||
| - Improve debug-level logging for package installation, and time how long installing each | - Improve debug-level logging for package installation, and time how long installing each | ||||||
|   package takes. Contributed by [Rebecca |   package takes. Contributed by [Rebecca | ||||||
|   Turner](https://github.com/9999years). |   Turner](https://github.com/9999years) (#63). | ||||||
| - Fix crash caused by the package-under-test depending on Poetry's unsafe dependencies ([#65](https://github.com/enpaul/tox-poetry-installer/issues/65)) | - Fix crash caused by the package-under-test depending on Poetry's unsafe dependencies ([#65](https://github.com/enpaul/tox-poetry-installer/issues/65)) | ||||||
|  |  | ||||||
| ## Version 0.8.1 | ## Version 0.8.1 | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -33,7 +33,7 @@ test: ## Run the project testsuite(s) | |||||||
| 	poetry run tox --recreate | 	poetry run tox --recreate | ||||||
|  |  | ||||||
| dev: ## Create the local dev environment | dev: ## Create the local dev environment | ||||||
| 	poetry install -E poetry | 	poetry install --extras poetry --sync | ||||||
| 	poetry run pre-commit install | 	poetry run pre-commit install | ||||||
|  |  | ||||||
| publish: test wheel source ## Build and upload to pypi (requires $PYPI_API_KEY be set) | publish: test wheel source ## Build and upload to pypi (requires $PYPI_API_KEY be set) | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								README.md
									
									
									
									
									
								
							| @@ -34,16 +34,16 @@ See the | |||||||
| [Changelog](https://github.com/enpaul/tox-poetry-installer/blob/devel/CHANGELOG.md) for | [Changelog](https://github.com/enpaul/tox-poetry-installer/blob/devel/CHANGELOG.md) for | ||||||
| release history. | release history. | ||||||
|  |  | ||||||
| *See also: [official Tox plugins](https://tox.readthedocs.io/en/latest/plugins.html), [Poetry-Dev-Dependencies Tox plugin](https://github.com/sinoroc/tox-poetry-dev-dependencies), [Poetry Tox plugin](https://github.com/tkukushkin/tox-poetry)* | *See also: [official Tox plugins](https://tox.readthedocs.io/en/latest/plugins.html), [Poetry Tox plugin](https://github.com/tkukushkin/tox-poetry)* | ||||||
|  |  | ||||||
| ## Feature Overview | ## Feature Overview | ||||||
|  |  | ||||||
| - Manage package versions in exactly one place and with exactly one tool: Poetry. | - Manage package versions in exactly one place and with exactly one tool: Poetry. | ||||||
| - Ensure CI/CD and other automation tools are using the same package versions that you are | - Ensure CI/CD and other automation tools are using the same package versions that you are | ||||||
|   in your local development environment. |   in your local development environment. | ||||||
| - Add only the packages you need to a Tox test environment, instead of everything in your | - Add only the packages or custom groups you need to a Tox test environment, instead of | ||||||
|   lockfile. |   everything in your lockfile. | ||||||
| - Directly integrate with Poetry, re-using your existing package indexes and credentials | - Directly integrate with Poetry, re-using your existing package indexes and credentials, | ||||||
|   with no additional configuration. |   with no additional configuration. | ||||||
| - Wherever possible, built-in Tox config options are always respected and their behavior | - Wherever possible, built-in Tox config options are always respected and their behavior | ||||||
|   kept consistent. |   kept consistent. | ||||||
| @@ -151,19 +151,23 @@ commands = ... | |||||||
| > the child environment with a different value. | > the child environment with a different value. | ||||||
|  |  | ||||||
| Alternatively, we can skip specifying all of our dependencies for a test environment in | Alternatively, we can skip specifying all of our dependencies for a test environment in | ||||||
| the Tox config and just install all of our Poetry dev-dependencies automatically: | the Tox config and install Poetry dependency groups directly: | ||||||
|  |  | ||||||
| ```ini | ```ini | ||||||
| [testenv] | [testenv] | ||||||
| description = Some very cool tests | description = Some very cool tests | ||||||
| require_locked_deps = true | require_locked_deps = true | ||||||
| install_dev_deps = true | poetry_dep_groups = | ||||||
|  |     dev | ||||||
| commands = ... | commands = ... | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| > **Note:** Setting `install_dev_deps = true` on an environment that also installs the | > **Note:** Setting `poetry_dep_groups = [dev]` on an environment that also installs the | ||||||
| > project package is functionally equivalent to running `poetry install`. | > project package is functionally equivalent to running `poetry install`. | ||||||
|  |  | ||||||
|  | > **Note:** The `install_dev_deps` configuration option is deprecated. See [Configuration | ||||||
|  | > Options](#configuration-options) for more information. | ||||||
|  |  | ||||||
| Finally, we can also install an unlocked dependency (a dependency which doesn't take its | Finally, we can also install an unlocked dependency (a dependency which doesn't take its | ||||||
| version from the Poetry lockfile) into the test environment alongside the locked ones. We | version from the Poetry lockfile) into the test environment alongside the locked ones. We | ||||||
| need to remove the `require_locked_deps = true` option, otherwise the environment will | need to remove the `require_locked_deps = true` option, otherwise the environment will | ||||||
| @@ -198,9 +202,13 @@ configuration section. | |||||||
| | :--------------------- | :-----: | :-----: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | | :--------------------- | :-----: | :-----: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||||||
| | `locked_deps`          |  List   |  `[]`   | Names of packages to install to the test environment from the Poetry lockfile. Transient dependencies (packages required by these dependencies) are automatically included.                                                                                                                                                                                          | | | `locked_deps`          |  List   |  `[]`   | Names of packages to install to the test environment from the Poetry lockfile. Transient dependencies (packages required by these dependencies) are automatically included.                                                                                                                                                                                          | | ||||||
| | `require_locked_deps`  | Boolean |  False  | Whether the plugin should block attempts to install unlocked dependencies to the test environment. If enabled, then the [`tox_testenv_install_deps`](https://tox.readthedocs.io/en/latest/plugins.html#tox.hookspecs.tox_testenv_install_deps) plugin hook will be intercepted and an error will be raised if the test environment has the `deps` option configured. | | | `require_locked_deps`  | Boolean |  False  | Whether the plugin should block attempts to install unlocked dependencies to the test environment. If enabled, then the [`tox_testenv_install_deps`](https://tox.readthedocs.io/en/latest/plugins.html#tox.hookspecs.tox_testenv_install_deps) plugin hook will be intercepted and an error will be raised if the test environment has the `deps` option configured. | | ||||||
| | `install_dev_deps`     | Boolean |  False  | Whether all of the Poetry dev-dependencies should be installed to the test environment.                                                                                                                                                                                                                                                                              | |  | ||||||
| | `install_project_deps` | Boolean |  True   | Whether all of the Poetry primary dependencies for the project package should be installed to the test environment.                                                                                                                                                                                                                                                  | | | `install_project_deps` | Boolean |  True   | Whether all of the Poetry primary dependencies for the project package should be installed to the test environment.                                                                                                                                                                                                                                                  | | ||||||
| | `require_poetry`       | Boolean |  False  | Whether Tox should be forced to fail if the plugin cannot import Poetry locally. If `False` then the plugin will be skipped for the test environment if Poetry cannot be imported. If `True` then the plugin will force the environment to error and the Tox run to fail.                                                                                            | | | `require_poetry`       | Boolean |  False  | Whether Tox should be forced to fail if the plugin cannot import Poetry locally. If `False` then the plugin will be skipped for the test environment if Poetry cannot be imported. If `True` then the plugin will force the environment to error and the Tox run to fail.                                                                                            | | ||||||
|  | | `poetry_dep_groups`    |  List   |  `[]`   | Names of Poetry dependency groups specified in `pyproject.toml` to install to the test environment.                                                                                                                                                                                                                                                                  | | ||||||
|  |  | ||||||
|  | > **Note:** The `install_dev_deps` configuration option is deprecated and will be removed in | ||||||
|  | > version 1.0.0. Please set `poetry_dep_groups = [dev]` in `tox.ini` for environments that | ||||||
|  | > install the development dependencies. | ||||||
|  |  | ||||||
| ### Runtime Options | ### Runtime Options | ||||||
|  |  | ||||||
| @@ -230,7 +238,7 @@ error will be set to one of the "Status" values below to indicate what the error | |||||||
| | `LockedDepVersionConflictError` | Indicates that an item in the `locked_deps` config option includes a [PEP-508 version specifier](https://www.python.org/dev/peps/pep-0508/#grammar) (ex: `pytest >=6.0, <6.1`).                                                 | | | `LockedDepVersionConflictError` | Indicates that an item in the `locked_deps` config option includes a [PEP-508 version specifier](https://www.python.org/dev/peps/pep-0508/#grammar) (ex: `pytest >=6.0, <6.1`).                                                 | | ||||||
| | `LockedDepNotFoundError`        | Indicates that an item specified in the `locked_deps` config option does not match the name of a package in the Poetry lockfile.                                                                                                | | | `LockedDepNotFoundError`        | Indicates that an item specified in the `locked_deps` config option does not match the name of a package in the Poetry lockfile.                                                                                                | | ||||||
| | `LockedDepsRequiredError`       | Indicates that a test environment with the `require_locked_deps` config option set to `true` also specified unlocked dependencies using the [`deps`](https://tox.readthedocs.io/en/latest/config.html#conf-deps) config option. | | | `LockedDepsRequiredError`       | Indicates that a test environment with the `require_locked_deps` config option set to `true` also specified unlocked dependencies using the [`deps`](https://tox.readthedocs.io/en/latest/config.html#conf-deps) config option. | | ||||||
| | `PoetryNotInstalledError`       | Indicates that the `poetry` module could not be imported under the current runtime environment, and the `--require-poetry` flag was provided.                                                                                   | | | `PoetryNotInstalledError`       | Indicates that the `poetry` module could not be imported under the current runtime environment, and `require_poetry = true` was specified.                                                                                      | | ||||||
| | `RequiresUnsafeDepError`        | Indicates that the package-under-test depends on a package that Poetry has classified as unsafe and cannot be installed.                                                                                                        | | | `RequiresUnsafeDepError`        | Indicates that the package-under-test depends on a package that Poetry has classified as unsafe and cannot be installed.                                                                                                        | | ||||||
|  |  | ||||||
| > **Note:** One or more of these errors can be caused by the `pyproject.toml` being out of | > **Note:** One or more of these errors can be caused by the `pyproject.toml` being out of | ||||||
| @@ -353,7 +361,7 @@ are tracked on [Github](https://github.com/enpaul/tox-poetry-installer/releases) | |||||||
|   and [open a pull request](https://github.com/enpaul/tox-poetry-installer/compare). |   and [open a pull request](https://github.com/enpaul/tox-poetry-installer/compare). | ||||||
|  |  | ||||||
| Developing this project requires [Python 3.7+](https://www.python.org/downloads/) and | Developing this project requires [Python 3.7+](https://www.python.org/downloads/) and | ||||||
| [Poetry 1.0](https://python-poetry.org/docs/#installation) or later. GNU Make can | [Poetry 1.2](https://python-poetry.org/docs/#installation) or later. GNU Make can | ||||||
| optionally be used to quickly setup a local development environment, but this is not | optionally be used to quickly setup a local development environment, but this is not | ||||||
| required. | required. | ||||||
|  |  | ||||||
| @@ -368,18 +376,11 @@ git clone git@github.com:enpaul/tox-poetry-installer.git | |||||||
|  |  | ||||||
| cd tox-poetry-installer/ | cd tox-poetry-installer/ | ||||||
|  |  | ||||||
| # Create and configure the local development environment... | # Create and configure the local development environment | ||||||
| # ...with make: |  | ||||||
| make dev | make dev | ||||||
| # ...manually: |  | ||||||
| poetry install -E poetry --remove-untracked |  | ||||||
| poetry run pre-commit install |  | ||||||
|  |  | ||||||
| # Run tests and CI locally... | # Run tests and CI locally | ||||||
| # ...with make: |  | ||||||
| make test | make test | ||||||
| # ...manually: |  | ||||||
| poetry run tox --recreate |  | ||||||
|  |  | ||||||
| # See additional make targets | # See additional make targets | ||||||
| make help | make help | ||||||
|   | |||||||
							
								
								
									
										3071
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3071
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| [tool.poetry] | [tool.poetry] | ||||||
| name = "tox-poetry-installer" | name = "tox-poetry-installer" | ||||||
| version = "0.8.3" | version = "0.10.1" | ||||||
| license = "MIT" | license = "MIT" | ||||||
| authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"] | authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"] | ||||||
| description = "A plugin for Tox that lets you install test environment dependencies from the Poetry lockfile" | description = "A plugin for Tox that lets you install test environment dependencies from the Poetry lockfile" | ||||||
| @@ -23,11 +23,11 @@ classifiers = [ | |||||||
|   "Natural Language :: English", |   "Natural Language :: English", | ||||||
|   "Operating System :: OS Independent", |   "Operating System :: OS Independent", | ||||||
|   "Programming Language :: Python :: 3", |   "Programming Language :: Python :: 3", | ||||||
|   "Programming Language :: Python :: 3.6", |  | ||||||
|   "Programming Language :: Python :: 3.7", |   "Programming Language :: Python :: 3.7", | ||||||
|   "Programming Language :: Python :: 3.8", |   "Programming Language :: Python :: 3.8", | ||||||
|   "Programming Language :: Python :: 3.9", |   "Programming Language :: Python :: 3.9", | ||||||
|   "Programming Language :: Python :: 3.10", |   "Programming Language :: Python :: 3.10", | ||||||
|  |   "Programming Language :: Python :: 3.11", | ||||||
|   "Programming Language :: Python :: Implementation :: CPython", |   "Programming Language :: Python :: Implementation :: CPython", | ||||||
| ] | ] | ||||||
|  |  | ||||||
| @@ -35,33 +35,39 @@ classifiers = [ | |||||||
| poetry_installer = "tox_poetry_installer" | poetry_installer = "tox_poetry_installer" | ||||||
|  |  | ||||||
| [tool.poetry.extras] | [tool.poetry.extras] | ||||||
| poetry = ["poetry"] | poetry = ["poetry", "cleo"] | ||||||
|  |  | ||||||
| [tool.poetry.dependencies] | [tool.poetry.dependencies] | ||||||
| python = "^3.6.1" | python = "^3.7" | ||||||
| poetry = {version = "^1.0.0", optional = true} | cleo = {version = ">=1.0,<3.0", optional = true} | ||||||
| poetry-core = "^1.0.0" | poetry = {version = "^1.2.0", optional = true} | ||||||
|  | poetry-core = "^1.1.0" | ||||||
| tox = "^3.8.0" | tox = "^3.8.0" | ||||||
|  |  | ||||||
| [tool.poetry.dev-dependencies] | [tool.poetry.group.dev.dependencies] | ||||||
| bandit = "^1.6.2" | bandit = "^1.6.2" | ||||||
| black = {version = "^21.12b0", allow-prereleases = true, python = "^3.7"} | black = "^22.3.0" | ||||||
| blacken-docs = "^1.8.0" | blacken-docs = "^1.8.0" | ||||||
| ipython = { version = "^7.18.1", python = "^3.7" } | ipython = {version = "^8.10.1", python = "^3.8"} | ||||||
| mdformat = "^0.6" | mdformat = "^0.6" | ||||||
| mdformat-gfm = "^0.2" | mdformat-gfm = "^0.2" | ||||||
| mypy = "^0.930" | mypy = "^0.930" | ||||||
| pre-commit = "^2.7.1" | pre-commit = "^2.7.1" | ||||||
| pre-commit-hooks = "^3.3.0" | pre-commit-hooks = "^3.3.0" | ||||||
| pylint = "^2.4.4" | pylint = "^2.13.0" | ||||||
| pytest = "^6.0.2" | pytest = "^6.0.2" | ||||||
| pytest-cov = "^2.10.1" | pytest-cov = "^2.10.1" | ||||||
| reorder-python-imports = "^2.3.5" | reorder-python-imports = "^2.3.5" | ||||||
| safety = "^1.9.0" | safety = "^2.2.0" | ||||||
| toml = "^0.10.1" | toml = "^0.10.1" | ||||||
| tox = "^3.20.0" | tox = "^3.20.0" | ||||||
| types-toml = "^0.10.1" | types-toml = "^0.10.1" | ||||||
|  | # This is a workaround for this issue with the Poetry export | ||||||
|  | # plugin which was blocking the 'security' CI check: | ||||||
|  | # | ||||||
|  | # https://github.com/python-poetry/poetry-plugin-export/issues/176 | ||||||
|  | virtualenv = ">=20.15,<20.16" | ||||||
|  |  | ||||||
| [build-system] | [build-system] | ||||||
| requires = ["poetry-core>=1.0.0"] | requires = ["poetry-core>=1.1.0"] | ||||||
| build-backend = "poetry.core.masonry.api" | build-backend = "poetry.core.masonry.api" | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import poetry.installation.pip_installer | |||||||
| import poetry.utils.env | import poetry.utils.env | ||||||
| import pytest | import pytest | ||||||
| import tox | import tox | ||||||
| from poetry.core.packages import Package as PoetryPackage | from poetry.core.packages.package import Package as PoetryPackage | ||||||
|  |  | ||||||
| from tox_poetry_installer import utilities | from tox_poetry_installer import utilities | ||||||
|  |  | ||||||
| @@ -31,6 +31,10 @@ class MockVirtualEnv: | |||||||
|     def is_valid_for_marker(*args, **kwargs): |     def is_valid_for_marker(*args, **kwargs): | ||||||
|         return True |         return True | ||||||
|  |  | ||||||
|  |     @staticmethod | ||||||
|  |     def get_version_info(): | ||||||
|  |         return (1, 2, 3) | ||||||
|  |  | ||||||
|  |  | ||||||
| class MockPipInstaller: | class MockPipInstaller: | ||||||
|     """Mock class for the :class:`poetry.installation.pip_installer.PipInstaller`""" |     """Mock class for the :class:`poetry.installation.pip_installer.PipInstaller`""" | ||||||
|   | |||||||
| @@ -6,15 +6,15 @@ from poetry.factory import Factory | |||||||
|  |  | ||||||
| from .fixtures import mock_poetry_factory | from .fixtures import mock_poetry_factory | ||||||
| from .fixtures import mock_venv | from .fixtures import mock_venv | ||||||
| from tox_poetry_installer import datatypes |  | ||||||
| from tox_poetry_installer import installer | from tox_poetry_installer import installer | ||||||
|  | from tox_poetry_installer import utilities | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_deduplication(mock_venv, mock_poetry_factory): | def test_deduplication(mock_venv, mock_poetry_factory): | ||||||
|     """Test that the installer does not install duplicate dependencies""" |     """Test that the installer does not install duplicate dependencies""" | ||||||
|     poetry = Factory().create_poetry(None) |     poetry = Factory().create_poetry(None) | ||||||
|     packages: datatypes.PackageMap = { |     packages: utilities.PackageMap = { | ||||||
|         item.name: item for item in poetry.locker.locked_repository(False).packages |         item.name: item for item in poetry.locker.locked_repository().packages | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     venv = tox.venv.VirtualEnv() |     venv = tox.venv.VirtualEnv() | ||||||
| @@ -28,8 +28,8 @@ def test_deduplication(mock_venv, mock_poetry_factory): | |||||||
| def test_parallelization(mock_venv, mock_poetry_factory): | def test_parallelization(mock_venv, mock_poetry_factory): | ||||||
|     """Test that behavior is consistent between parallel and non-parallel usage""" |     """Test that behavior is consistent between parallel and non-parallel usage""" | ||||||
|     poetry = Factory().create_poetry(None) |     poetry = Factory().create_poetry(None) | ||||||
|     packages: datatypes.PackageMap = { |     packages: utilities.PackageMap = { | ||||||
|         item.name: item for item in poetry.locker.locked_repository(False).packages |         item.name: item for item in poetry.locker.locked_repository().packages | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     to_install = [ |     to_install = [ | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ from poetry.puzzle.provider import Provider | |||||||
| from .fixtures import mock_poetry_factory | from .fixtures import mock_poetry_factory | ||||||
| from .fixtures import mock_venv | from .fixtures import mock_venv | ||||||
| from tox_poetry_installer import constants | from tox_poetry_installer import constants | ||||||
| from tox_poetry_installer import datatypes |  | ||||||
| from tox_poetry_installer import exceptions | from tox_poetry_installer import exceptions | ||||||
| from tox_poetry_installer import utilities | from tox_poetry_installer import utilities | ||||||
|  |  | ||||||
| @@ -58,17 +57,15 @@ def test_functional(mock_poetry_factory, mock_venv): | |||||||
|     is always the last in the returned list. |     is always the last in the returned list. | ||||||
|     """ |     """ | ||||||
|     pypoetry = poetry.factory.Factory().create_poetry(None) |     pypoetry = poetry.factory.Factory().create_poetry(None) | ||||||
|     packages: datatypes.PackageMap = { |     packages = utilities.build_package_map(pypoetry) | ||||||
|         item.name: item for item in pypoetry.locker.locked_repository(False).packages |  | ||||||
|     } |  | ||||||
|     venv = poetry.utils.env.VirtualEnv()  # pylint: disable=no-value-for-parameter |     venv = poetry.utils.env.VirtualEnv()  # pylint: disable=no-value-for-parameter | ||||||
|  |  | ||||||
|     requests_requires = [ |     requests_requires = [ | ||||||
|         packages["certifi"], |         packages["certifi"][0], | ||||||
|         packages["chardet"], |         packages["chardet"][0], | ||||||
|         packages["idna"], |         packages["idna"][0], | ||||||
|         packages["urllib3"], |         packages["urllib3"][0], | ||||||
|         packages["requests"], |         packages["requests"][0], | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     transients = utilities.identify_transients("requests", packages, venv) |     transients = utilities.identify_transients("requests", packages, venv) | ||||||
| @@ -76,7 +73,7 @@ def test_functional(mock_poetry_factory, mock_venv): | |||||||
|     assert all((item in requests_requires) for item in transients) |     assert all((item in requests_requires) for item in transients) | ||||||
|     assert all((item in transients) for item in requests_requires) |     assert all((item in transients) for item in requests_requires) | ||||||
|  |  | ||||||
|     for package in [packages["requests"], packages["tox"], packages["flask"]]: |     for package in [packages["requests"][0], packages["tox"][0], packages["flask"][0]]: | ||||||
|         transients = utilities.identify_transients(package, packages, venv) |         transients = utilities.identify_transients(package.name, packages, venv) | ||||||
|         assert transients[-1] == package |         assert transients[-1] == package | ||||||
|         assert len(transients) == len(set(transients)) |         assert len(transients) == len(set(transients)) | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								tox.ini
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								tox.ini
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | |||||||
| [tox] | [tox] | ||||||
| envlist = py36, py37, py38, py39, py310, static, static-tests, security | envlist = py37, py38, py39, py310, py311, static, static-tests, security | ||||||
| isolated_build = true | isolated_build = true | ||||||
| skip_missing_interpreters = true | skip_missing_interpreters = true | ||||||
|  |  | ||||||
| @@ -21,7 +21,7 @@ commands = | |||||||
|  |  | ||||||
| [testenv:static] | [testenv:static] | ||||||
| description = Static formatting and quality enforcement | description = Static formatting and quality enforcement | ||||||
| basepython = python3.8 | basepython = python3.10 | ||||||
| platform = linux | platform = linux | ||||||
| ignore_errors = true | ignore_errors = true | ||||||
| locked_deps = | locked_deps = | ||||||
| @@ -46,7 +46,7 @@ commands = | |||||||
|  |  | ||||||
| [testenv:static-tests] | [testenv:static-tests] | ||||||
| description = Static formatting and quality enforcement for the tests | description = Static formatting and quality enforcement for the tests | ||||||
| basepython = python3.8 | basepython = python3.10 | ||||||
| platform = linux | platform = linux | ||||||
| ignore_errors = true | ignore_errors = true | ||||||
| locked_deps = | locked_deps = | ||||||
| @@ -63,7 +63,7 @@ commands = | |||||||
|  |  | ||||||
| [testenv:security] | [testenv:security] | ||||||
| description = Security checks | description = Security checks | ||||||
| basepython = python3.8 | basepython = python3.10 | ||||||
| platform = linux | platform = linux | ||||||
| ignore_errors = true | ignore_errors = true | ||||||
| skip_install = true | skip_install = true | ||||||
| @@ -83,7 +83,10 @@ commands = | |||||||
|       --format requirements.txt \ |       --format requirements.txt \ | ||||||
|       --output {envtmpdir}/requirements.txt \ |       --output {envtmpdir}/requirements.txt \ | ||||||
|       --without-hashes \ |       --without-hashes \ | ||||||
|       --dev |       --with dev \ | ||||||
|  |       --extras poetry | ||||||
|     safety check \ |     safety check \ | ||||||
|       --file {envtmpdir}/requirements.txt \ |       --file {envtmpdir}/requirements.txt \ | ||||||
|       --json |       --output text \ | ||||||
|  |       # https://github.com/pytest-dev/py/issues/287 | ||||||
|  |       --ignore 51457 | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| # pylint: disable=missing-docstring | # pylint: disable=missing-docstring | ||||||
| __title__ = "tox-poetry-installer" | __title__ = "tox-poetry-installer" | ||||||
| __summary__ = "A plugin for Tox that lets you install test environment dependencies from the Poetry lockfile" | __summary__ = "A plugin for Tox that lets you install test environment dependencies from the Poetry lockfile" | ||||||
| __version__ = "0.8.3" | __version__ = "0.10.1" | ||||||
| __url__ = "https://github.com/enpaul/tox-poetry-installer/" | __url__ = "https://github.com/enpaul/tox-poetry-installer/" | ||||||
| __license__ = "MIT" | __license__ = "MIT" | ||||||
| __authors__ = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"] | __authors__ = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"] | ||||||
|   | |||||||
| @@ -28,9 +28,9 @@ from tox_poetry_installer import exceptions | |||||||
|  |  | ||||||
|  |  | ||||||
| try: | try: | ||||||
|  |     from cleo.io.null_io import NullIO | ||||||
|     from poetry.factory import Factory |     from poetry.factory import Factory | ||||||
|     from poetry.installation.pip_installer import PipInstaller |     from poetry.installation.pip_installer import PipInstaller | ||||||
|     from poetry.io.null_io import NullIO |  | ||||||
|     from poetry.poetry import Poetry |     from poetry.poetry import Poetry | ||||||
|     from poetry.utils.env import VirtualEnv |     from poetry.utils.env import VirtualEnv | ||||||
| except ImportError: | except ImportError: | ||||||
|   | |||||||
| @@ -20,7 +20,8 @@ PEP508_VERSION_DELIMITERS: Tuple[str, ...] = ("~=", "==", "!=", ">", "<") | |||||||
| REPORTER_PREFIX: str = f"{__about__.__title__}:" | REPORTER_PREFIX: str = f"{__about__.__title__}:" | ||||||
|  |  | ||||||
| # Internal list of packages that poetry has deemed unsafe and are excluded from the lockfile | # Internal list of packages that poetry has deemed unsafe and are excluded from the lockfile | ||||||
| UNSAFE_PACKAGES: Set[str] = {"distribute", "pip", "setuptools", "wheel"} | # TODO: This functionality is no longer needed, should remove in a future update. | ||||||
|  | UNSAFE_PACKAGES: Set[str] = set() | ||||||
|  |  | ||||||
| # Number of threads to use for installing dependencies by default | # Number of threads to use for installing dependencies by default | ||||||
| DEFAULT_INSTALL_THREADS: int = 10 | DEFAULT_INSTALL_THREADS: int = 10 | ||||||
|   | |||||||
| @@ -1,8 +0,0 @@ | |||||||
| """Definitions for typehints/containers used by the plugin""" |  | ||||||
| from typing import Dict |  | ||||||
|  |  | ||||||
| from poetry.core.packages import Package as PoetryPackage |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # Map of package names to the package object |  | ||||||
| PackageMap = Dict[str, PoetryPackage] |  | ||||||
| @@ -4,6 +4,7 @@ All implementations of tox hooks are defined here, as well as any single-use hel | |||||||
| specifically related to implementing the hooks (to keep the size/readability of the hook functions | specifically related to implementing the hooks (to keep the size/readability of the hook functions | ||||||
| themselves manageable). | themselves manageable). | ||||||
| """ | """ | ||||||
|  | from itertools import chain | ||||||
| from typing import Optional | from typing import Optional | ||||||
|  |  | ||||||
| import tox | import tox | ||||||
| @@ -17,7 +18,6 @@ from tox_poetry_installer import exceptions | |||||||
| from tox_poetry_installer import installer | from tox_poetry_installer import installer | ||||||
| from tox_poetry_installer import logger | from tox_poetry_installer import logger | ||||||
| from tox_poetry_installer import utilities | from tox_poetry_installer import utilities | ||||||
| from tox_poetry_installer.datatypes import PackageMap |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _postprocess_install_project_deps( | def _postprocess_install_project_deps( | ||||||
| @@ -115,7 +115,14 @@ def tox_addoption(parser: ToxParser): | |||||||
|         name="install_dev_deps", |         name="install_dev_deps", | ||||||
|         type="bool", |         type="bool", | ||||||
|         default=False, |         default=False, | ||||||
|         help="Automatically install all Poetry development dependencies to the environment", |         help="(deprecated) Automatically install all Poetry development dependencies to the environment", | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     parser.add_testenv_attribute( | ||||||
|  |         name="poetry_dep_groups", | ||||||
|  |         type="line-list", | ||||||
|  |         default=[], | ||||||
|  |         help="List of Poetry dependency groups to install to the environment", | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     parser.add_testenv_attribute( |     parser.add_testenv_attribute( | ||||||
| @@ -186,10 +193,7 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional | |||||||
|                 f"Unlocked dependencies '{venv.envconfig.deps}' specified for environment '{venv.name}' which requires locked dependencies" |                 f"Unlocked dependencies '{venv.envconfig.deps}' specified for environment '{venv.name}' which requires locked dependencies" | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|         packages: PackageMap = { |         packages = utilities.build_package_map(poetry) | ||||||
|             package.name: package |  | ||||||
|             for package in poetry.locker.locked_repository(True).packages |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if venv.envconfig.install_dev_deps: |         if venv.envconfig.install_dev_deps: | ||||||
|             dev_deps = utilities.find_dev_deps(packages, virtualenv, poetry) |             dev_deps = utilities.find_dev_deps(packages, virtualenv, poetry) | ||||||
| @@ -200,6 +204,20 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional | |||||||
|             dev_deps = [] |             dev_deps = [] | ||||||
|             logger.info("Env does not install development dependencies, skipping") |             logger.info("Env does not install development dependencies, skipping") | ||||||
|  |  | ||||||
|  |         group_deps = utilities.dedupe_packages( | ||||||
|  |             list( | ||||||
|  |                 chain( | ||||||
|  |                     *[ | ||||||
|  |                         utilities.find_group_deps(group, packages, virtualenv, poetry) | ||||||
|  |                         for group in venv.envconfig.poetry_dep_groups | ||||||
|  |                     ] | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  |         logger.info( | ||||||
|  |             f"Identified {len(group_deps)} group dependencies to install to env" | ||||||
|  |         ) | ||||||
|  |  | ||||||
|         env_deps = utilities.find_additional_deps( |         env_deps = utilities.find_additional_deps( | ||||||
|             packages, virtualenv, poetry, venv.envconfig.locked_deps |             packages, virtualenv, poetry, venv.envconfig.locked_deps | ||||||
|         ) |         ) | ||||||
| @@ -235,7 +253,9 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional | |||||||
|         logger.error(f"Internal plugin error: {err}") |         logger.error(f"Internal plugin error: {err}") | ||||||
|         raise err |         raise err | ||||||
|  |  | ||||||
|     dependencies = dev_deps + env_deps + project_deps |     dependencies = utilities.dedupe_packages( | ||||||
|  |         dev_deps + group_deps + env_deps + project_deps | ||||||
|  |     ) | ||||||
|     if ( |     if ( | ||||||
|         venv.envconfig.config.option.parallel_install_threads |         venv.envconfig.config.option.parallel_install_threads | ||||||
|         != constants.DEFAULT_INSTALL_THREADS |         != constants.DEFAULT_INSTALL_THREADS | ||||||
|   | |||||||
| @@ -6,10 +6,10 @@ import concurrent.futures | |||||||
| import contextlib | import contextlib | ||||||
| import typing | import typing | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
| from typing import Sequence | from typing import Collection | ||||||
| from typing import Set | from typing import Set | ||||||
|  |  | ||||||
| from poetry.core.packages import Package as PoetryPackage | from poetry.core.packages.package import Package as PoetryPackage | ||||||
| from tox.venv import VirtualEnv as ToxVirtualEnv | from tox.venv import VirtualEnv as ToxVirtualEnv | ||||||
|  |  | ||||||
| from tox_poetry_installer import logger | from tox_poetry_installer import logger | ||||||
| @@ -22,7 +22,7 @@ if typing.TYPE_CHECKING: | |||||||
| def install( | def install( | ||||||
|     poetry: "_poetry.Poetry", |     poetry: "_poetry.Poetry", | ||||||
|     venv: ToxVirtualEnv, |     venv: ToxVirtualEnv, | ||||||
|     packages: Sequence[PoetryPackage], |     packages: Collection[PoetryPackage], | ||||||
|     parallels: int = 0, |     parallels: int = 0, | ||||||
| ): | ): | ||||||
|     """Install a bunch of packages to a virtualenv |     """Install a bunch of packages to a virtualenv | ||||||
|   | |||||||
| @@ -2,27 +2,30 @@ | |||||||
| # Silence this one globally to support the internal function imports for the proxied poetry module. | # Silence this one globally to support the internal function imports for the proxied poetry module. | ||||||
| # See the docstring in 'tox_poetry_installer._poetry' for more context. | # See the docstring in 'tox_poetry_installer._poetry' for more context. | ||||||
| # pylint: disable=import-outside-toplevel | # pylint: disable=import-outside-toplevel | ||||||
|  | import collections | ||||||
| import typing | import typing | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
|  | from typing import Dict | ||||||
| from typing import List | from typing import List | ||||||
| from typing import Sequence | from typing import Sequence | ||||||
| from typing import Set | from typing import Set | ||||||
| from typing import Union |  | ||||||
|  |  | ||||||
| from poetry.core.packages import Dependency as PoetryDependency | from poetry.core.packages.dependency import Dependency as PoetryDependency | ||||||
| from poetry.core.packages import Package as PoetryPackage | from poetry.core.packages.package import Package as PoetryPackage | ||||||
| from tox.action import Action as ToxAction | from tox.action import Action as ToxAction | ||||||
| from tox.venv import VirtualEnv as ToxVirtualEnv | from tox.venv import VirtualEnv as ToxVirtualEnv | ||||||
|  |  | ||||||
| from tox_poetry_installer import constants | from tox_poetry_installer import constants | ||||||
| from tox_poetry_installer import exceptions | from tox_poetry_installer import exceptions | ||||||
| from tox_poetry_installer import logger | from tox_poetry_installer import logger | ||||||
| from tox_poetry_installer.datatypes import PackageMap |  | ||||||
|  |  | ||||||
| if typing.TYPE_CHECKING: | if typing.TYPE_CHECKING: | ||||||
|     from tox_poetry_installer import _poetry |     from tox_poetry_installer import _poetry | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PackageMap = Dict[str, List[PoetryPackage]] | ||||||
|  |  | ||||||
|  |  | ||||||
| def check_preconditions(venv: ToxVirtualEnv, action: ToxAction) -> "_poetry.Poetry": | def check_preconditions(venv: ToxVirtualEnv, action: ToxAction) -> "_poetry.Poetry": | ||||||
|     """Check that the local project environment meets expectations""" |     """Check that the local project environment meets expectations""" | ||||||
|     # Skip running the plugin for the provisioning environment. The provisioned environment, |     # Skip running the plugin for the provisioning environment. The provisioned environment, | ||||||
| @@ -56,6 +59,13 @@ def check_preconditions(venv: ToxVirtualEnv, action: ToxAction) -> "_poetry.Poet | |||||||
|             "be removed in version 1.0.0. Please use the '--parallel-install-threads' option." |             "be removed in version 1.0.0. Please use the '--parallel-install-threads' option." | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  |     if venv.envconfig.install_dev_deps: | ||||||
|  |         logger.warning( | ||||||
|  |             "DEPRECATION: The 'install_dev_deps' option is deprecated and will be removed in " | ||||||
|  |             "version 1.0.0. Please update test environments that install development dependencies " | ||||||
|  |             "to set the 'poetry_dev_groups = [dev]' option in tox.ini" | ||||||
|  |         ) | ||||||
|  |  | ||||||
|     from tox_poetry_installer import _poetry |     from tox_poetry_installer import _poetry | ||||||
|  |  | ||||||
|     try: |     try: | ||||||
| @@ -82,16 +92,29 @@ def convert_virtualenv(venv: ToxVirtualEnv) -> "_poetry.VirtualEnv": | |||||||
|     return _poetry.VirtualEnv(path=Path(venv.envconfig.envdir)) |     return _poetry.VirtualEnv(path=Path(venv.envconfig.envdir)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def build_package_map(poetry: "_poetry.Poetry") -> PackageMap: | ||||||
|  |     """Build the mapping of package names to objects | ||||||
|  |  | ||||||
|  |     :param poetry: Populated poetry object to load locked packages from | ||||||
|  |     :returns: Mapping of package names to Poetry package objects | ||||||
|  |     """ | ||||||
|  |     packages = collections.defaultdict(list) | ||||||
|  |     for package in poetry.locker.locked_repository().packages: | ||||||
|  |         packages[package.name].append(package) | ||||||
|  |  | ||||||
|  |     return packages | ||||||
|  |  | ||||||
|  |  | ||||||
| def identify_transients( | def identify_transients( | ||||||
|     dep: Union[PoetryDependency, str], |     dep_name: str, | ||||||
|     packages: PackageMap, |     packages: PackageMap, | ||||||
|     venv: "_poetry.VirtualEnv", |     venv: "_poetry.VirtualEnv", | ||||||
|     allow_missing: Sequence[str] = (), |     allow_missing: Sequence[str] = (), | ||||||
| ) -> List[PoetryPackage]: | ) -> List[PoetryPackage]: | ||||||
|     """Using a pool of packages, identify all transient dependencies of a given package name |     """Using a pool of packages, identify all transient dependencies of a given package name | ||||||
|  |  | ||||||
|     :param dep: Either the Poetry dependency or the dependency's bare package name to recursively |     :param dep_name: Either the Poetry dependency or the dependency's bare package name to recursively | ||||||
|                 identify the transient dependencies of |                      identify the transient dependencies of | ||||||
|     :param packages: All packages from the lockfile to use for identifying dependency relationships. |     :param packages: All packages from the lockfile to use for identifying dependency relationships. | ||||||
|     :param venv: Poetry virtual environment to use for package compatibility checks |     :param venv: Poetry virtual environment to use for package compatibility checks | ||||||
|     :param allow_missing: Sequence of package names to allow to be missing from the lockfile. Any |     :param allow_missing: Sequence of package names to allow to be missing from the lockfile. Any | ||||||
| @@ -102,53 +125,64 @@ def identify_transients( | |||||||
|     .. note:: The package corresponding to the dependency specified by the ``dep`` parameter will |     .. note:: The package corresponding to the dependency specified by the ``dep`` parameter will | ||||||
|               be included in the returned list of packages. |               be included in the returned list of packages. | ||||||
|     """ |     """ | ||||||
|     transients: List[PoetryPackage] = [] |  | ||||||
|     searched: Set[str] = set() |     searched: Set[str] = set() | ||||||
|  |  | ||||||
|     def _deps_of_dep(transient: PoetryDependency): |     def _transients(transient: PoetryDependency) -> List[PoetryPackage]: | ||||||
|         searched.add(transient.name) |         searched.add(transient.name) | ||||||
|  |  | ||||||
|         if venv.is_valid_for_marker(transient.marker): |         results: List[PoetryPackage] = [] | ||||||
|             for requirement in packages[transient.name].requires: |         for option in packages[transient.name]: | ||||||
|                 if requirement.name not in searched: |             if venv.is_valid_for_marker(option.to_dependency().marker): | ||||||
|                     _deps_of_dep(requirement) |                 for requirement in option.requires: | ||||||
|             logger.debug(f"Including {transient} for installation") |                     if requirement.name not in searched: | ||||||
|             transients.append(packages[transient.name]) |                         results += _transients(requirement) | ||||||
|  |                 logger.debug(f"Including {option} for installation") | ||||||
|  |                 results.append(option) | ||||||
|  |                 break | ||||||
|         else: |         else: | ||||||
|             logger.debug(f"Skipping {transient}: package requires {transient.marker}") |             logger.debug( | ||||||
|  |                 f"Skipping {transient.name}: target python version is {'.'.join([str(item) for item in venv.get_version_info()])} but package requires {transient.marker}" | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |         return results | ||||||
|  |  | ||||||
|     try: |     try: | ||||||
|         if isinstance(dep, str): |         for option in packages[dep_name]: | ||||||
|             dep = packages[dep].to_dependency() |             if venv.is_valid_for_marker(option.to_dependency().marker): | ||||||
|  |                 dep = option.to_dependency() | ||||||
|         _deps_of_dep(dep) |                 break | ||||||
|     except KeyError as err: |         else: | ||||||
|         dep_name = err.args[0] |  | ||||||
|  |  | ||||||
|         if dep_name in constants.UNSAFE_PACKAGES: |  | ||||||
|             logger.warning( |             logger.warning( | ||||||
|                 f"Installing package '{dep_name}' using Poetry is not supported and will be skipped" |                 f"Skipping {dep_name}: no locked version found compatible with target python version {'.'.join([str(item) for item in venv.get_version_info()])}" | ||||||
|             ) |             ) | ||||||
|             logger.debug(f"Skipping {dep_name}: designated unsafe by Poetry") |  | ||||||
|             return [] |             return [] | ||||||
|  |  | ||||||
|         if dep_name in allow_missing: |         return _transients(dep) | ||||||
|             logger.debug(f"Skipping {dep_name}: package is allowed to be unlocked") |     except KeyError as err: | ||||||
|  |         missing = err.args[0] | ||||||
|  |  | ||||||
|  |         if missing in constants.UNSAFE_PACKAGES: | ||||||
|  |             logger.warning( | ||||||
|  |                 f"Installing package '{missing}' using Poetry is not supported and will be skipped" | ||||||
|  |             ) | ||||||
|  |             logger.debug(f"Skipping {missing}: designated unsafe by Poetry") | ||||||
|  |             return [] | ||||||
|  |  | ||||||
|  |         if missing in allow_missing: | ||||||
|  |             logger.debug(f"Skipping {missing}: package is allowed to be unlocked") | ||||||
|             return [] |             return [] | ||||||
|  |  | ||||||
|         if any( |         if any( | ||||||
|             delimiter in dep_name for delimiter in constants.PEP508_VERSION_DELIMITERS |             delimiter in missing for delimiter in constants.PEP508_VERSION_DELIMITERS | ||||||
|         ): |         ): | ||||||
|             raise exceptions.LockedDepVersionConflictError( |             raise exceptions.LockedDepVersionConflictError( | ||||||
|                 f"Locked dependency '{dep_name}' cannot include version specifier" |                 f"Locked dependency '{missing}' cannot include version specifier" | ||||||
|             ) from None |             ) from None | ||||||
|  |  | ||||||
|         raise exceptions.LockedDepNotFoundError( |         raise exceptions.LockedDepNotFoundError( | ||||||
|             f"No version of locked dependency '{dep_name}' found in the project lockfile" |             f"No version of locked dependency '{missing}' found in the project lockfile" | ||||||
|         ) from None |         ) from None | ||||||
|  |  | ||||||
|     return transients |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def find_project_deps( | def find_project_deps( | ||||||
|     packages: PackageMap, |     packages: PackageMap, | ||||||
| @@ -171,29 +205,27 @@ def find_project_deps( | |||||||
|             f"Project package requires one or more unsafe dependencies ({', '.join(constants.UNSAFE_PACKAGES)}) which cannot be installed with Poetry" |             f"Project package requires one or more unsafe dependencies ({', '.join(constants.UNSAFE_PACKAGES)}) which cannot be installed with Poetry" | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     base_deps: List[PoetryPackage] = [ |     required_dep_names = [ | ||||||
|         packages[item.name] |         item.name for item in poetry.package.requires if not item.is_optional() | ||||||
|         for item in poetry.package.requires |  | ||||||
|         if not item.is_optional() |  | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     extra_deps: List[PoetryPackage] = [] |     extra_dep_names: List[str] = [] | ||||||
|     for extra in extras: |     for extra in extras: | ||||||
|         logger.info(f"Processing project extra '{extra}'") |         logger.info(f"Processing project extra '{extra}'") | ||||||
|         try: |         try: | ||||||
|             extra_deps += [packages[item.name] for item in poetry.package.extras[extra]] |             extra_dep_names += [item.name for item in poetry.package.extras[extra]] | ||||||
|         except KeyError: |         except KeyError: | ||||||
|             raise exceptions.ExtraNotFoundError( |             raise exceptions.ExtraNotFoundError( | ||||||
|                 f"Environment specifies project extra '{extra}' which was not found in the lockfile" |                 f"Environment specifies project extra '{extra}' which was not found in the lockfile" | ||||||
|             ) from None |             ) from None | ||||||
|  |  | ||||||
|     dependencies: List[PoetryPackage] = [] |     dependencies: List[PoetryPackage] = [] | ||||||
|     for dep in base_deps + extra_deps: |     for dep_name in required_dep_names + extra_dep_names: | ||||||
|         dependencies += identify_transients( |         dependencies += identify_transients( | ||||||
|             dep.name.lower(), packages, venv, allow_missing=[poetry.package.name] |             dep_name.lower(), packages, venv, allow_missing=[poetry.package.name] | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     return dependencies |     return dedupe_packages(dependencies) | ||||||
|  |  | ||||||
|  |  | ||||||
| def find_additional_deps( | def find_additional_deps( | ||||||
| @@ -212,13 +244,40 @@ def find_additional_deps( | |||||||
|     :param dep_names: Sequence of additional dependency names to recursively find the transient |     :param dep_names: Sequence of additional dependency names to recursively find the transient | ||||||
|                       dependencies for |                       dependencies for | ||||||
|     """ |     """ | ||||||
|     deps: List[PoetryPackage] = [] |     dependencies: List[PoetryPackage] = [] | ||||||
|     for dep_name in dep_names: |     for dep_name in dep_names: | ||||||
|         deps += identify_transients( |         dependencies += identify_transients( | ||||||
|             dep_name.lower(), packages, venv, allow_missing=[poetry.package.name] |             dep_name.lower(), packages, venv, allow_missing=[poetry.package.name] | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     return deps |     return dedupe_packages(dependencies) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def find_group_deps( | ||||||
|  |     group: str, | ||||||
|  |     packages: PackageMap, | ||||||
|  |     venv: "_poetry.VirtualEnv", | ||||||
|  |     poetry: "_poetry.Poetry", | ||||||
|  | ) -> List[PoetryPackage]: | ||||||
|  |     """Find the dependencies belonging to a dependency group | ||||||
|  |  | ||||||
|  |     Recursively identify the Poetry dev dependencies | ||||||
|  |  | ||||||
|  |     :param group: Name of the dependency group from the project's ``pyproject.toml`` | ||||||
|  |     :param packages: Mapping of all locked package names to their corresponding package object | ||||||
|  |     :param venv: Poetry virtual environment to use for package compatibility checks | ||||||
|  |     :param poetry: Poetry object for the current project | ||||||
|  |     """ | ||||||
|  |     return find_additional_deps( | ||||||
|  |         packages, | ||||||
|  |         venv, | ||||||
|  |         poetry, | ||||||
|  |         poetry.pyproject.data["tool"]["poetry"] | ||||||
|  |         .get("group", {}) | ||||||
|  |         .get(group, {}) | ||||||
|  |         .get("dependencies", {}) | ||||||
|  |         .keys(), | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
| def find_dev_deps( | def find_dev_deps( | ||||||
| @@ -232,9 +291,26 @@ def find_dev_deps( | |||||||
|     :param venv: Poetry virtual environment to use for package compatibility checks |     :param venv: Poetry virtual environment to use for package compatibility checks | ||||||
|     :param poetry: Poetry object for the current project |     :param poetry: Poetry object for the current project | ||||||
|     """ |     """ | ||||||
|     return find_additional_deps( |     dev_group_deps = find_group_deps("dev", packages, venv, poetry) | ||||||
|  |  | ||||||
|  |     # Legacy pyproject.toml poetry format: | ||||||
|  |     legacy_dev_group_deps = find_additional_deps( | ||||||
|         packages, |         packages, | ||||||
|         venv, |         venv, | ||||||
|         poetry, |         poetry, | ||||||
|         poetry.pyproject.data["tool"]["poetry"].get("dev-dependencies", {}).keys(), |         poetry.pyproject.data["tool"]["poetry"].get("dev-dependencies", {}).keys(), | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |     # Poetry 1.2 unions these two toml sections. | ||||||
|  |     return dedupe_packages(dev_group_deps + legacy_dev_group_deps) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def dedupe_packages(packages: Sequence[PoetryPackage]) -> List[PoetryPackage]: | ||||||
|  |     """Deduplicates a sequence of PoetryPackages while preserving ordering | ||||||
|  |  | ||||||
|  |     Adapted from StackOverflow: https://stackoverflow.com/a/480227 | ||||||
|  |     """ | ||||||
|  |     seen: Set[PoetryPackage] = set() | ||||||
|  |     # Make this faster, avoid method lookup below | ||||||
|  |     seen_add = seen.add | ||||||
|  |     return [p for p in packages if not (p in seen or seen_add(p))] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user