FerrellSyntheticIntelligence commited on
Commit
f2dda64
·
verified ·
1 Parent(s): f530c59

remove venv/cache junk from failed first upload

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .pytest_cache/.gitignore +0 -2
  2. .pytest_cache/CACHEDIR.TAG +0 -4
  3. .pytest_cache/README.md +0 -8
  4. .pytest_cache/v/cache/lastfailed +0 -1
  5. .pytest_cache/v/cache/nodeids +0 -71
  6. .venv/bin/Activate.ps1 +0 -247
  7. .venv/bin/activate +0 -70
  8. .venv/bin/activate.csh +0 -27
  9. .venv/bin/activate.fish +0 -69
  10. .venv/bin/debugpy +0 -6
  11. .venv/bin/debugpy-adapter +0 -6
  12. .venv/bin/f2py +0 -6
  13. .venv/bin/gguf-convert-endian +0 -6
  14. .venv/bin/gguf-dump +0 -6
  15. .venv/bin/gguf-editor-gui +0 -6
  16. .venv/bin/gguf-new-metadata +0 -6
  17. .venv/bin/gguf-set-metadata +0 -6
  18. .venv/bin/hf +0 -6
  19. .venv/bin/httpx +0 -6
  20. .venv/bin/huggingface-cli +0 -6
  21. .venv/bin/idna +0 -6
  22. .venv/bin/isympy +0 -6
  23. .venv/bin/markdown-it +0 -6
  24. .venv/bin/normalizer +0 -6
  25. .venv/bin/numpy-config +0 -6
  26. .venv/bin/pip +0 -8
  27. .venv/bin/pip3 +0 -8
  28. .venv/bin/pip3.12 +0 -8
  29. .venv/bin/py-spy +0 -3
  30. .venv/bin/py.test +0 -6
  31. .venv/bin/pygmentize +0 -6
  32. .venv/bin/pytest +0 -6
  33. .venv/bin/python +0 -3
  34. .venv/bin/python3 +0 -3
  35. .venv/bin/python3.12 +0 -3
  36. .venv/bin/tiny-agents +0 -6
  37. .venv/bin/torchfrtrace +0 -6
  38. .venv/bin/torchrun +0 -6
  39. .venv/bin/tqdm +0 -6
  40. .venv/bin/transformers +0 -6
  41. .venv/bin/typer +0 -6
  42. .venv/lib/python3.12/site-packages/_distutils_hack/__init__.py +0 -239
  43. .venv/lib/python3.12/site-packages/_distutils_hack/override.py +0 -1
  44. .venv/lib/python3.12/site-packages/_pytest/__init__.py +0 -13
  45. .venv/lib/python3.12/site-packages/_pytest/_argcomplete.py +0 -117
  46. .venv/lib/python3.12/site-packages/_pytest/_code/__init__.py +0 -26
  47. .venv/lib/python3.12/site-packages/_pytest/_code/code.py +0 -1632
  48. .venv/lib/python3.12/site-packages/_pytest/_code/source.py +0 -228
  49. .venv/lib/python3.12/site-packages/_pytest/_io/__init__.py +0 -10
  50. .venv/lib/python3.12/site-packages/_pytest/_io/pprint.py +0 -673
.pytest_cache/.gitignore DELETED
@@ -1,2 +0,0 @@
1
- # Created by pytest automatically.
2
- *
 
 
 
.pytest_cache/CACHEDIR.TAG DELETED
@@ -1,4 +0,0 @@
1
- Signature: 8a477f597d28d172789f06886806bc55
2
- # This file is a cache directory tag created by pytest.
3
- # For information about cache directory tags, see:
4
- # https://bford.info/cachedir/spec.html
 
 
 
 
 
.pytest_cache/README.md DELETED
@@ -1,8 +0,0 @@
1
- # pytest cache directory #
2
-
3
- This directory contains data from the pytest's cache plugin,
4
- which provides the `--lf` and `--ff` options, as well as the `cache` fixture.
5
-
6
- **Do not** commit this to version control.
7
-
8
- See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information.
 
 
 
 
 
 
 
 
 
.pytest_cache/v/cache/lastfailed DELETED
@@ -1 +0,0 @@
1
- {}
 
 
.pytest_cache/v/cache/nodeids DELETED
@@ -1,71 +0,0 @@
1
- [
2
- "tests/test_decision.py::test_accuracy_vs_coverage_monotone",
3
- "tests/test_decision.py::test_bucket_abstention_curve",
4
- "tests/test_decision.py::test_bucket_for",
5
- "tests/test_decision.py::test_conflict_attenuated",
6
- "tests/test_decision.py::test_majority_outweighs_minority",
7
- "tests/test_decision.py::test_unanimous_high_vote",
8
- "tests/test_decision.py::test_unanimous_low_abstains",
9
- "tests/test_decision.py::test_unknown_bucket_abstains_above_zero_threshold",
10
- "tests/test_decision.py::test_weighted_tally",
11
- "tests/test_dpo_lfm2.py::test_apo_term_rewards_absolute_gap",
12
- "tests/test_dpo_lfm2.py::test_margin_increases_loss_for_close_pairs",
13
- "tests/test_dpo_lfm2.py::test_plain_dpo_special_case",
14
- "tests/test_dpo_lr_schedule.py::test_constant_schedule_keeps_lr",
15
- "tests/test_dpo_lr_schedule.py::test_cosine_warmup_then_decay",
16
- "tests/test_dpo_lr_schedule.py::test_warmup_frac_scales",
17
- "tests/test_eval_summary.py::test_scored_ids_whole_file",
18
- "tests/test_eval_summary.py::test_summarize_dedupes_resume_sections",
19
- "tests/test_eval_summary.py::test_summarize_exact",
20
- "tests/test_guardrails.py::test_clean_research_input_passes",
21
- "tests/test_guardrails.py::test_instruction_override_flagged",
22
- "tests/test_guardrails.py::test_offtopic_flagged",
23
- "tests/test_guardrails.py::test_output_abstain_mismatch_flagged",
24
- "tests/test_guardrails.py::test_output_clean_passes",
25
- "tests/test_guardrails.py::test_output_valid_missing_confidence_flagged",
26
- "tests/test_guardrails.py::test_pii_redacted",
27
- "tests/test_guardrails.py::test_roleplay_extraction_flagged",
28
- "tests/test_helix_memory.py::test_helix_forget_and_stats",
29
- "tests/test_helix_memory.py::test_helix_recall_bridges_cases_and_keeps_receipts",
30
- "tests/test_journalism.py::test_casefile_roundtrip",
31
- "tests/test_journalism.py::test_editorial_review_clean",
32
- "tests/test_journalism.py::test_editorial_review_flags",
33
- "tests/test_journalism.py::test_entitygraph_edges_and_centrality",
34
- "tests/test_journalism.py::test_framing_omissions",
35
- "tests/test_journalism.py::test_framing_passive_loaded_hedges",
36
- "tests/test_journalism.py::test_patterns_shared_rungs_and_themes",
37
- "tests/test_journalism.py::test_provenance_chain_and_single_source",
38
- "tests/test_journalism.py::test_provenance_credibility_tiers",
39
- "tests/test_journalism.py::test_source_policy_rejects_untraceable_or_duplicate_leads",
40
- "tests/test_journalism.py::test_source_policy_requires_independent_traceable_corroboration",
41
- "tests/test_journalism.py::test_suite_report_end_to_end",
42
- "tests/test_journalism.py::test_suite_report_fails_closed_without_source_policy_metadata",
43
- "tests/test_journalism.py::test_timeline_anachronism",
44
- "tests/test_journalism.py::test_timeline_gaps_and_cliffs",
45
- "tests/test_lora_fold.py::test_fold_preserves_bias",
46
- "tests/test_merges.py::test_soup_taskarith_intersect_keys",
47
- "tests/test_merges.py::test_ties_merge_ignores_missing_task_keys",
48
- "tests/test_merges.py::test_trim_delta_preserves_top_fraction_shape",
49
- "tests/test_mtp.py::test_forward_mtp_shapes",
50
- "tests/test_mtp.py::test_mtp_checkpoint_roundtrip",
51
- "tests/test_mtp.py::test_mtp_loss_backward",
52
- "tests/test_mtp.py::test_train_lm_mtp_smoke",
53
- "tests/test_posttrain.py::test_rlvr_card_trace",
54
- "tests/test_posttrain.py::test_rlvr_reward_abstain_is_zero",
55
- "tests/test_posttrain.py::test_rlvr_reward_correct_with_citation",
56
- "tests/test_posttrain.py::test_rlvr_reward_false_citation_penalty",
57
- "tests/test_posttrain.py::test_rlvr_reward_wrong_verdict",
58
- "tests/test_posttrain.py::test_ties_sign_consensus",
59
- "tests/test_posttrain.py::test_trim_keeps_topk",
60
- "tests/test_verify_loop.py::test_plan_checks_extracts_values",
61
- "tests/test_verify_loop.py::test_run_checks_no_evidence",
62
- "tests/test_verify_loop.py::test_run_checks_refutes",
63
- "tests/test_verify_loop.py::test_run_checks_supports",
64
- "tests/test_verify_loop.py::test_strict_policy_fails_closed_on_a_single_untraceable_lead",
65
- "tests/test_verify_loop.py::test_strict_policy_overrides_an_incorrect_model_draft",
66
- "tests/test_verify_loop.py::test_verify_case_defaults_to_fail_closed_source_policy",
67
- "tests/test_verify_loop.py::test_verify_case_rule_refuted_wins",
68
- "tests/test_verify_loop.py::test_verify_case_rule_verified",
69
- "tests/test_verify_loop.py::test_verify_case_unresolved_downgrades_high",
70
- "tests/test_verify_loop.py::test_verify_case_unresolved_keeps_low"
71
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/bin/Activate.ps1 DELETED
@@ -1,247 +0,0 @@
1
- <#
2
- .Synopsis
3
- Activate a Python virtual environment for the current PowerShell session.
4
-
5
- .Description
6
- Pushes the python executable for a virtual environment to the front of the
7
- $Env:PATH environment variable and sets the prompt to signify that you are
8
- in a Python virtual environment. Makes use of the command line switches as
9
- well as the `pyvenv.cfg` file values present in the virtual environment.
10
-
11
- .Parameter VenvDir
12
- Path to the directory that contains the virtual environment to activate. The
13
- default value for this is the parent of the directory that the Activate.ps1
14
- script is located within.
15
-
16
- .Parameter Prompt
17
- The prompt prefix to display when this virtual environment is activated. By
18
- default, this prompt is the name of the virtual environment folder (VenvDir)
19
- surrounded by parentheses and followed by a single space (ie. '(.venv) ').
20
-
21
- .Example
22
- Activate.ps1
23
- Activates the Python virtual environment that contains the Activate.ps1 script.
24
-
25
- .Example
26
- Activate.ps1 -Verbose
27
- Activates the Python virtual environment that contains the Activate.ps1 script,
28
- and shows extra information about the activation as it executes.
29
-
30
- .Example
31
- Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
32
- Activates the Python virtual environment located in the specified location.
33
-
34
- .Example
35
- Activate.ps1 -Prompt "MyPython"
36
- Activates the Python virtual environment that contains the Activate.ps1 script,
37
- and prefixes the current prompt with the specified string (surrounded in
38
- parentheses) while the virtual environment is active.
39
-
40
- .Notes
41
- On Windows, it may be required to enable this Activate.ps1 script by setting the
42
- execution policy for the user. You can do this by issuing the following PowerShell
43
- command:
44
-
45
- PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
46
-
47
- For more information on Execution Policies:
48
- https://go.microsoft.com/fwlink/?LinkID=135170
49
-
50
- #>
51
- Param(
52
- [Parameter(Mandatory = $false)]
53
- [String]
54
- $VenvDir,
55
- [Parameter(Mandatory = $false)]
56
- [String]
57
- $Prompt
58
- )
59
-
60
- <# Function declarations --------------------------------------------------- #>
61
-
62
- <#
63
- .Synopsis
64
- Remove all shell session elements added by the Activate script, including the
65
- addition of the virtual environment's Python executable from the beginning of
66
- the PATH variable.
67
-
68
- .Parameter NonDestructive
69
- If present, do not remove this function from the global namespace for the
70
- session.
71
-
72
- #>
73
- function global:deactivate ([switch]$NonDestructive) {
74
- # Revert to original values
75
-
76
- # The prior prompt:
77
- if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
78
- Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
79
- Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
80
- }
81
-
82
- # The prior PYTHONHOME:
83
- if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
84
- Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
85
- Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
86
- }
87
-
88
- # The prior PATH:
89
- if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
90
- Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
91
- Remove-Item -Path Env:_OLD_VIRTUAL_PATH
92
- }
93
-
94
- # Just remove the VIRTUAL_ENV altogether:
95
- if (Test-Path -Path Env:VIRTUAL_ENV) {
96
- Remove-Item -Path env:VIRTUAL_ENV
97
- }
98
-
99
- # Just remove VIRTUAL_ENV_PROMPT altogether.
100
- if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
101
- Remove-Item -Path env:VIRTUAL_ENV_PROMPT
102
- }
103
-
104
- # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
105
- if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
106
- Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
107
- }
108
-
109
- # Leave deactivate function in the global namespace if requested:
110
- if (-not $NonDestructive) {
111
- Remove-Item -Path function:deactivate
112
- }
113
- }
114
-
115
- <#
116
- .Description
117
- Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
118
- given folder, and returns them in a map.
119
-
120
- For each line in the pyvenv.cfg file, if that line can be parsed into exactly
121
- two strings separated by `=` (with any amount of whitespace surrounding the =)
122
- then it is considered a `key = value` line. The left hand string is the key,
123
- the right hand is the value.
124
-
125
- If the value starts with a `'` or a `"` then the first and last character is
126
- stripped from the value before being captured.
127
-
128
- .Parameter ConfigDir
129
- Path to the directory that contains the `pyvenv.cfg` file.
130
- #>
131
- function Get-PyVenvConfig(
132
- [String]
133
- $ConfigDir
134
- ) {
135
- Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
136
-
137
- # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
138
- $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
139
-
140
- # An empty map will be returned if no config file is found.
141
- $pyvenvConfig = @{ }
142
-
143
- if ($pyvenvConfigPath) {
144
-
145
- Write-Verbose "File exists, parse `key = value` lines"
146
- $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
147
-
148
- $pyvenvConfigContent | ForEach-Object {
149
- $keyval = $PSItem -split "\s*=\s*", 2
150
- if ($keyval[0] -and $keyval[1]) {
151
- $val = $keyval[1]
152
-
153
- # Remove extraneous quotations around a string value.
154
- if ("'""".Contains($val.Substring(0, 1))) {
155
- $val = $val.Substring(1, $val.Length - 2)
156
- }
157
-
158
- $pyvenvConfig[$keyval[0]] = $val
159
- Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
160
- }
161
- }
162
- }
163
- return $pyvenvConfig
164
- }
165
-
166
-
167
- <# Begin Activate script --------------------------------------------------- #>
168
-
169
- # Determine the containing directory of this script
170
- $VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
171
- $VenvExecDir = Get-Item -Path $VenvExecPath
172
-
173
- Write-Verbose "Activation script is located in path: '$VenvExecPath'"
174
- Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
175
- Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
176
-
177
- # Set values required in priority: CmdLine, ConfigFile, Default
178
- # First, get the location of the virtual environment, it might not be
179
- # VenvExecDir if specified on the command line.
180
- if ($VenvDir) {
181
- Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
182
- }
183
- else {
184
- Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
185
- $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
186
- Write-Verbose "VenvDir=$VenvDir"
187
- }
188
-
189
- # Next, read the `pyvenv.cfg` file to determine any required value such
190
- # as `prompt`.
191
- $pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
192
-
193
- # Next, set the prompt from the command line, or the config file, or
194
- # just use the name of the virtual environment folder.
195
- if ($Prompt) {
196
- Write-Verbose "Prompt specified as argument, using '$Prompt'"
197
- }
198
- else {
199
- Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
200
- if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
201
- Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
202
- $Prompt = $pyvenvCfg['prompt'];
203
- }
204
- else {
205
- Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
206
- Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
207
- $Prompt = Split-Path -Path $venvDir -Leaf
208
- }
209
- }
210
-
211
- Write-Verbose "Prompt = '$Prompt'"
212
- Write-Verbose "VenvDir='$VenvDir'"
213
-
214
- # Deactivate any currently active virtual environment, but leave the
215
- # deactivate function in place.
216
- deactivate -nondestructive
217
-
218
- # Now set the environment variable VIRTUAL_ENV, used by many tools to determine
219
- # that there is an activated venv.
220
- $env:VIRTUAL_ENV = $VenvDir
221
-
222
- if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
223
-
224
- Write-Verbose "Setting prompt to '$Prompt'"
225
-
226
- # Set the prompt to include the env name
227
- # Make sure _OLD_VIRTUAL_PROMPT is global
228
- function global:_OLD_VIRTUAL_PROMPT { "" }
229
- Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
230
- New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
231
-
232
- function global:prompt {
233
- Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
234
- _OLD_VIRTUAL_PROMPT
235
- }
236
- $env:VIRTUAL_ENV_PROMPT = $Prompt
237
- }
238
-
239
- # Clear PYTHONHOME
240
- if (Test-Path -Path Env:PYTHONHOME) {
241
- Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
242
- Remove-Item -Path Env:PYTHONHOME
243
- }
244
-
245
- # Add the venv to the PATH
246
- Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
247
- $Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/bin/activate DELETED
@@ -1,70 +0,0 @@
1
- # This file must be used with "source bin/activate" *from bash*
2
- # You cannot run it directly
3
-
4
- deactivate () {
5
- # reset old environment variables
6
- if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
7
- PATH="${_OLD_VIRTUAL_PATH:-}"
8
- export PATH
9
- unset _OLD_VIRTUAL_PATH
10
- fi
11
- if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
12
- PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
13
- export PYTHONHOME
14
- unset _OLD_VIRTUAL_PYTHONHOME
15
- fi
16
-
17
- # Call hash to forget past commands. Without forgetting
18
- # past commands the $PATH changes we made may not be respected
19
- hash -r 2> /dev/null
20
-
21
- if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
22
- PS1="${_OLD_VIRTUAL_PS1:-}"
23
- export PS1
24
- unset _OLD_VIRTUAL_PS1
25
- fi
26
-
27
- unset VIRTUAL_ENV
28
- unset VIRTUAL_ENV_PROMPT
29
- if [ ! "${1:-}" = "nondestructive" ] ; then
30
- # Self destruct!
31
- unset -f deactivate
32
- fi
33
- }
34
-
35
- # unset irrelevant variables
36
- deactivate nondestructive
37
-
38
- # on Windows, a path can contain colons and backslashes and has to be converted:
39
- if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then
40
- # transform D:\path\to\venv to /d/path/to/venv on MSYS
41
- # and to /cygdrive/d/path/to/venv on Cygwin
42
- export VIRTUAL_ENV=$(cygpath /root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv)
43
- else
44
- # use the path as-is
45
- export VIRTUAL_ENV=/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv
46
- fi
47
-
48
- _OLD_VIRTUAL_PATH="$PATH"
49
- PATH="$VIRTUAL_ENV/"bin":$PATH"
50
- export PATH
51
-
52
- # unset PYTHONHOME if set
53
- # this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
54
- # could use `if (set -u; : $PYTHONHOME) ;` in bash
55
- if [ -n "${PYTHONHOME:-}" ] ; then
56
- _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
57
- unset PYTHONHOME
58
- fi
59
-
60
- if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
61
- _OLD_VIRTUAL_PS1="${PS1:-}"
62
- PS1='(.venv) '"${PS1:-}"
63
- export PS1
64
- VIRTUAL_ENV_PROMPT='(.venv) '
65
- export VIRTUAL_ENV_PROMPT
66
- fi
67
-
68
- # Call hash to forget past commands. Without forgetting
69
- # past commands the $PATH changes we made may not be respected
70
- hash -r 2> /dev/null
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/bin/activate.csh DELETED
@@ -1,27 +0,0 @@
1
- # This file must be used with "source bin/activate.csh" *from csh*.
2
- # You cannot run it directly.
3
-
4
- # Created by Davide Di Blasi <davidedb@gmail.com>.
5
- # Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
6
-
7
- alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate'
8
-
9
- # Unset irrelevant variables.
10
- deactivate nondestructive
11
-
12
- setenv VIRTUAL_ENV /root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv
13
-
14
- set _OLD_VIRTUAL_PATH="$PATH"
15
- setenv PATH "$VIRTUAL_ENV/"bin":$PATH"
16
-
17
-
18
- set _OLD_VIRTUAL_PROMPT="$prompt"
19
-
20
- if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
21
- set prompt = '(.venv) '"$prompt"
22
- setenv VIRTUAL_ENV_PROMPT '(.venv) '
23
- endif
24
-
25
- alias pydoc python -m pydoc
26
-
27
- rehash
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/bin/activate.fish DELETED
@@ -1,69 +0,0 @@
1
- # This file must be used with "source <venv>/bin/activate.fish" *from fish*
2
- # (https://fishshell.com/). You cannot run it directly.
3
-
4
- function deactivate -d "Exit virtual environment and return to normal shell environment"
5
- # reset old environment variables
6
- if test -n "$_OLD_VIRTUAL_PATH"
7
- set -gx PATH $_OLD_VIRTUAL_PATH
8
- set -e _OLD_VIRTUAL_PATH
9
- end
10
- if test -n "$_OLD_VIRTUAL_PYTHONHOME"
11
- set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
12
- set -e _OLD_VIRTUAL_PYTHONHOME
13
- end
14
-
15
- if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
16
- set -e _OLD_FISH_PROMPT_OVERRIDE
17
- # prevents error when using nested fish instances (Issue #93858)
18
- if functions -q _old_fish_prompt
19
- functions -e fish_prompt
20
- functions -c _old_fish_prompt fish_prompt
21
- functions -e _old_fish_prompt
22
- end
23
- end
24
-
25
- set -e VIRTUAL_ENV
26
- set -e VIRTUAL_ENV_PROMPT
27
- if test "$argv[1]" != "nondestructive"
28
- # Self-destruct!
29
- functions -e deactivate
30
- end
31
- end
32
-
33
- # Unset irrelevant variables.
34
- deactivate nondestructive
35
-
36
- set -gx VIRTUAL_ENV /root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv
37
-
38
- set -gx _OLD_VIRTUAL_PATH $PATH
39
- set -gx PATH "$VIRTUAL_ENV/"bin $PATH
40
-
41
- # Unset PYTHONHOME if set.
42
- if set -q PYTHONHOME
43
- set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
44
- set -e PYTHONHOME
45
- end
46
-
47
- if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
48
- # fish uses a function instead of an env var to generate the prompt.
49
-
50
- # Save the current fish_prompt function as the function _old_fish_prompt.
51
- functions -c fish_prompt _old_fish_prompt
52
-
53
- # With the original prompt function renamed, we can override with our own.
54
- function fish_prompt
55
- # Save the return status of the last command.
56
- set -l old_status $status
57
-
58
- # Output the venv prompt; color taken from the blue of the Python logo.
59
- printf "%s%s%s" (set_color 4B8BBE) '(.venv) ' (set_color normal)
60
-
61
- # Restore the return status of the previous command.
62
- echo "exit $old_status" | .
63
- # Output the original/"old" prompt.
64
- _old_fish_prompt
65
- end
66
-
67
- set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
68
- set -gx VIRTUAL_ENV_PROMPT '(.venv) '
69
- end
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/bin/debugpy DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from debugpy.server.cli import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/debugpy-adapter DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from debugpy.adapter.__main__ import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/f2py DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from numpy.f2py.f2py2e import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/gguf-convert-endian DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from gguf.scripts.gguf_convert_endian import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/gguf-dump DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from gguf.scripts.gguf_dump import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/gguf-editor-gui DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from gguf.scripts.gguf_editor_gui import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/gguf-new-metadata DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from gguf.scripts.gguf_new_metadata import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/gguf-set-metadata DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from gguf.scripts.gguf_set_metadata import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/hf DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from huggingface_hub.cli.hf import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/httpx DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from httpx import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/huggingface-cli DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from huggingface_hub.cli.deprecated_cli import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/idna DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from idna.cli import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/isympy DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from isympy import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/markdown-it DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from markdown_it.cli.parse import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/normalizer DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from charset_normalizer.cli import cli_detect
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(cli_detect())
 
 
 
 
 
 
 
.venv/bin/numpy-config DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from numpy._configtool import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/pip DELETED
@@ -1,8 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- # -*- coding: utf-8 -*-
3
- import re
4
- import sys
5
- from pip._internal.cli.main import main
6
- if __name__ == '__main__':
7
- sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
8
- sys.exit(main())
 
 
 
 
 
 
 
 
 
.venv/bin/pip3 DELETED
@@ -1,8 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- # -*- coding: utf-8 -*-
3
- import re
4
- import sys
5
- from pip._internal.cli.main import main
6
- if __name__ == '__main__':
7
- sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
8
- sys.exit(main())
 
 
 
 
 
 
 
 
 
.venv/bin/pip3.12 DELETED
@@ -1,8 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- # -*- coding: utf-8 -*-
3
- import re
4
- import sys
5
- from pip._internal.cli.main import main
6
- if __name__ == '__main__':
7
- sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
8
- sys.exit(main())
 
 
 
 
 
 
 
 
 
.venv/bin/py-spy DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:d33e743ff7962b4aeefaa34ee87ae1b35e047967f983d660c5335602cb44fba5
3
- size 7537232
 
 
 
 
.venv/bin/py.test DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from _pytest.config import _console_main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(_console_main())
 
 
 
 
 
 
 
.venv/bin/pygmentize DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from pygments.cmdline import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/pytest DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from _pytest.config import _console_main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(_console_main())
 
 
 
 
 
 
 
.venv/bin/python DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:6242e0e8650d7dbdebbc25e08bf4c9359ddaf65f54fcae0e57fa99395fa5357a
3
- size 7845032
 
 
 
 
.venv/bin/python3 DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:6242e0e8650d7dbdebbc25e08bf4c9359ddaf65f54fcae0e57fa99395fa5357a
3
- size 7845032
 
 
 
 
.venv/bin/python3.12 DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:6242e0e8650d7dbdebbc25e08bf4c9359ddaf65f54fcae0e57fa99395fa5357a
3
- size 7845032
 
 
 
 
.venv/bin/tiny-agents DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from huggingface_hub.inference._mcp.cli import app
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(app())
 
 
 
 
 
 
 
.venv/bin/torchfrtrace DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from torch.distributed.flight_recorder.fr_trace import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/torchrun DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from torch.distributed.run import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/tqdm DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from tqdm.cli import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/transformers DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from transformers.cli.transformers import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/bin/typer DELETED
@@ -1,6 +0,0 @@
1
- #!/root/Documents/Codex/2026-07-31/so-i-ve-got-a-task/.venv/bin/python3
2
- import sys
3
- from typer.cli import main
4
- if __name__ == '__main__':
5
- sys.argv[0] = sys.argv[0].removesuffix('.exe')
6
- sys.exit(main())
 
 
 
 
 
 
 
.venv/lib/python3.12/site-packages/_distutils_hack/__init__.py DELETED
@@ -1,239 +0,0 @@
1
- # don't import any costly modules
2
- import os
3
- import sys
4
-
5
- report_url = (
6
- "https://github.com/pypa/setuptools/issues/new?template=distutils-deprecation.yml"
7
- )
8
-
9
-
10
- def warn_distutils_present():
11
- if 'distutils' not in sys.modules:
12
- return
13
- import warnings
14
-
15
- warnings.warn(
16
- "Distutils was imported before Setuptools, but importing Setuptools "
17
- "also replaces the `distutils` module in `sys.modules`. This may lead "
18
- "to undesirable behaviors or errors. To avoid these issues, avoid "
19
- "using distutils directly, ensure that setuptools is installed in the "
20
- "traditional way (e.g. not an editable install), and/or make sure "
21
- "that setuptools is always imported before distutils."
22
- )
23
-
24
-
25
- def clear_distutils():
26
- if 'distutils' not in sys.modules:
27
- return
28
- import warnings
29
-
30
- warnings.warn(
31
- "Setuptools is replacing distutils. Support for replacing "
32
- "an already imported distutils is deprecated. In the future, "
33
- "this condition will fail. "
34
- f"Register concerns at {report_url}"
35
- )
36
- mods = [
37
- name
38
- for name in sys.modules
39
- if name == "distutils" or name.startswith("distutils.")
40
- ]
41
- for name in mods:
42
- del sys.modules[name]
43
-
44
-
45
- def enabled():
46
- """
47
- Allow selection of distutils by environment variable.
48
- """
49
- which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'local')
50
- if which == 'stdlib':
51
- import warnings
52
-
53
- warnings.warn(
54
- "Reliance on distutils from stdlib is deprecated. Users "
55
- "must rely on setuptools to provide the distutils module. "
56
- "Avoid importing distutils or import setuptools first, "
57
- "and avoid setting SETUPTOOLS_USE_DISTUTILS=stdlib. "
58
- f"Register concerns at {report_url}"
59
- )
60
- return which == 'local'
61
-
62
-
63
- def ensure_local_distutils():
64
- import importlib
65
-
66
- clear_distutils()
67
-
68
- # With the DistutilsMetaFinder in place,
69
- # perform an import to cause distutils to be
70
- # loaded from setuptools._distutils. Ref #2906.
71
- with shim():
72
- importlib.import_module('distutils')
73
-
74
- # check that submodules load as expected
75
- core = importlib.import_module('distutils.core')
76
- assert '_distutils' in core.__file__, core.__file__
77
- assert 'setuptools._distutils.log' not in sys.modules
78
-
79
-
80
- def do_override():
81
- """
82
- Ensure that the local copy of distutils is preferred over stdlib.
83
-
84
- See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401
85
- for more motivation.
86
- """
87
- if enabled():
88
- warn_distutils_present()
89
- ensure_local_distutils()
90
-
91
-
92
- class _TrivialRe:
93
- def __init__(self, *patterns) -> None:
94
- self._patterns = patterns
95
-
96
- def match(self, string):
97
- return all(pat in string for pat in self._patterns)
98
-
99
-
100
- class DistutilsMetaFinder:
101
- def find_spec(self, fullname, path, target=None):
102
- # optimization: only consider top level modules and those
103
- # found in the CPython test suite.
104
- if path is not None and not fullname.startswith('test.'):
105
- return None
106
-
107
- method_name = 'spec_for_{fullname}'.format(**locals())
108
- method = getattr(self, method_name, lambda: None)
109
- return method()
110
-
111
- def spec_for_distutils(self):
112
- if self.is_cpython():
113
- return None
114
-
115
- import importlib
116
- import importlib.abc
117
- import importlib.util
118
-
119
- try:
120
- mod = importlib.import_module('setuptools._distutils')
121
- except Exception:
122
- # There are a couple of cases where setuptools._distutils
123
- # may not be present:
124
- # - An older Setuptools without a local distutils is
125
- # taking precedence. Ref #2957.
126
- # - Path manipulation during sitecustomize removes
127
- # setuptools from the path but only after the hook
128
- # has been loaded. Ref #2980.
129
- # In either case, fall back to stdlib behavior.
130
- return None
131
-
132
- class DistutilsLoader(importlib.abc.Loader):
133
- def create_module(self, spec):
134
- mod.__name__ = 'distutils'
135
- return mod
136
-
137
- def exec_module(self, module):
138
- pass
139
-
140
- return importlib.util.spec_from_loader(
141
- 'distutils', DistutilsLoader(), origin=mod.__file__
142
- )
143
-
144
- @staticmethod
145
- def is_cpython():
146
- """
147
- Suppress supplying distutils for CPython (build and tests).
148
- Ref #2965 and #3007.
149
- """
150
- return os.path.isfile('pybuilddir.txt')
151
-
152
- def spec_for_pip(self):
153
- """
154
- Ensure stdlib distutils when running under pip.
155
- See pypa/pip#8761 for rationale.
156
- """
157
- if sys.version_info >= (3, 12) or self.pip_imported_during_build():
158
- return
159
- clear_distutils()
160
- self.spec_for_distutils = lambda: None
161
-
162
- @classmethod
163
- def pip_imported_during_build(cls):
164
- """
165
- Detect if pip is being imported in a build script. Ref #2355.
166
- """
167
- import traceback
168
-
169
- return any(
170
- cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None)
171
- )
172
-
173
- @staticmethod
174
- def frame_file_is_setup(frame):
175
- """
176
- Return True if the indicated frame suggests a setup.py file.
177
- """
178
- # some frames may not have __file__ (#2940)
179
- return frame.f_globals.get('__file__', '').endswith('setup.py')
180
-
181
- def spec_for_sensitive_tests(self):
182
- """
183
- Ensure stdlib distutils when running select tests under CPython.
184
-
185
- python/cpython#91169
186
- """
187
- clear_distutils()
188
- self.spec_for_distutils = lambda: None
189
-
190
- sensitive_tests = (
191
- [
192
- 'test.test_distutils',
193
- 'test.test_peg_generator',
194
- 'test.test_importlib',
195
- ]
196
- if sys.version_info < (3, 10)
197
- else [
198
- 'test.test_distutils',
199
- ]
200
- )
201
-
202
-
203
- for name in DistutilsMetaFinder.sensitive_tests:
204
- setattr(
205
- DistutilsMetaFinder,
206
- f'spec_for_{name}',
207
- DistutilsMetaFinder.spec_for_sensitive_tests,
208
- )
209
-
210
-
211
- DISTUTILS_FINDER = DistutilsMetaFinder()
212
-
213
-
214
- def add_shim():
215
- DISTUTILS_FINDER in sys.meta_path or insert_shim()
216
-
217
-
218
- class shim:
219
- def __enter__(self) -> None:
220
- insert_shim()
221
-
222
- def __exit__(self, exc: object, value: object, tb: object) -> None:
223
- _remove_shim()
224
-
225
-
226
- def insert_shim():
227
- sys.meta_path.insert(0, DISTUTILS_FINDER)
228
-
229
-
230
- def _remove_shim():
231
- try:
232
- sys.meta_path.remove(DISTUTILS_FINDER)
233
- except ValueError:
234
- pass
235
-
236
-
237
- if sys.version_info < (3, 12):
238
- # DistutilsMetaFinder can only be disabled in Python < 3.12 (PEP 632)
239
- remove_shim = _remove_shim
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/lib/python3.12/site-packages/_distutils_hack/override.py DELETED
@@ -1 +0,0 @@
1
- __import__('_distutils_hack').do_override()
 
 
.venv/lib/python3.12/site-packages/_pytest/__init__.py DELETED
@@ -1,13 +0,0 @@
1
- from __future__ import annotations
2
-
3
-
4
- __all__ = ["__version__", "version_tuple"]
5
-
6
- try:
7
- from ._version import version as __version__
8
- from ._version import version_tuple
9
- except ImportError: # pragma: no cover
10
- # broken installation, we don't even try
11
- # unknown only works because we do poor mans version compare
12
- __version__ = "unknown"
13
- version_tuple = (0, 0, "unknown")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/lib/python3.12/site-packages/_pytest/_argcomplete.py DELETED
@@ -1,117 +0,0 @@
1
- """Allow bash-completion for argparse with argcomplete if installed.
2
-
3
- Needs argcomplete>=0.5.6 for python 3.2/3.3 (older versions fail
4
- to find the magic string, so _ARGCOMPLETE env. var is never set, and
5
- this does not need special code).
6
-
7
- Function try_argcomplete(parser) should be called directly before
8
- the call to ArgumentParser.parse_args().
9
-
10
- The filescompleter is what you normally would use on the positional
11
- arguments specification, in order to get "dirname/" after "dirn<TAB>"
12
- instead of the default "dirname ":
13
-
14
- optparser.add_argument(Config._file_or_dir, nargs='*').completer=filescompleter
15
-
16
- Other, application specific, completers should go in the file
17
- doing the add_argument calls as they need to be specified as .completer
18
- attributes as well. (If argcomplete is not installed, the function the
19
- attribute points to will not be used).
20
-
21
- SPEEDUP
22
- =======
23
-
24
- The generic argcomplete script for bash-completion
25
- (/etc/bash_completion.d/python-argcomplete.sh)
26
- uses a python program to determine startup script generated by pip.
27
- You can speed up completion somewhat by changing this script to include
28
- # PYTHON_ARGCOMPLETE_OK
29
- so the python-argcomplete-check-easy-install-script does not
30
- need to be called to find the entry point of the code and see if that is
31
- marked with PYTHON_ARGCOMPLETE_OK.
32
-
33
- INSTALL/DEBUGGING
34
- =================
35
-
36
- To include this support in another application that has setup.py generated
37
- scripts:
38
-
39
- - Add the line:
40
- # PYTHON_ARGCOMPLETE_OK
41
- near the top of the main python entry point.
42
-
43
- - Include in the file calling parse_args():
44
- from _argcomplete import try_argcomplete, filescompleter
45
- Call try_argcomplete just before parse_args(), and optionally add
46
- filescompleter to the positional arguments' add_argument().
47
-
48
- If things do not work right away:
49
-
50
- - Switch on argcomplete debugging with (also helpful when doing custom
51
- completers):
52
- export _ARC_DEBUG=1
53
-
54
- - Run:
55
- python-argcomplete-check-easy-install-script $(which appname)
56
- echo $?
57
- will echo 0 if the magic line has been found, 1 if not.
58
-
59
- - Sometimes it helps to find early on errors using:
60
- _ARGCOMPLETE=1 _ARC_DEBUG=1 appname
61
- which should throw a KeyError: 'COMPLINE' (which is properly set by the
62
- global argcomplete script).
63
- """
64
-
65
- from __future__ import annotations
66
-
67
- import argparse
68
- from glob import glob
69
- import os
70
- import sys
71
- from typing import Any
72
-
73
-
74
- class FastFilesCompleter:
75
- """Fast file completer class."""
76
-
77
- def __init__(self, directories: bool = True) -> None:
78
- self.directories = directories
79
-
80
- def __call__(self, prefix: str, **kwargs: Any) -> list[str]:
81
- # Only called on non option completions.
82
- if os.sep in prefix[1:]:
83
- prefix_dir = len(os.path.dirname(prefix) + os.sep)
84
- else:
85
- prefix_dir = 0
86
- completion = []
87
- globbed = []
88
- if "*" not in prefix and "?" not in prefix:
89
- # We are on unix, otherwise no bash.
90
- if not prefix or prefix[-1] == os.sep:
91
- globbed.extend(glob(prefix + ".*"))
92
- prefix += "*"
93
- globbed.extend(glob(prefix))
94
- for x in sorted(globbed):
95
- if os.path.isdir(x):
96
- x += "/"
97
- # Append stripping the prefix (like bash, not like compgen).
98
- completion.append(x[prefix_dir:])
99
- return completion
100
-
101
-
102
- if os.environ.get("_ARGCOMPLETE"):
103
- try:
104
- import argcomplete.completers
105
- except ImportError:
106
- sys.exit(-1)
107
- filescompleter: FastFilesCompleter | None = FastFilesCompleter()
108
-
109
- def try_argcomplete(parser: argparse.ArgumentParser) -> None:
110
- argcomplete.autocomplete(parser, always_complete_options=False)
111
-
112
- else:
113
-
114
- def try_argcomplete(parser: argparse.ArgumentParser) -> None:
115
- pass
116
-
117
- filescompleter = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/lib/python3.12/site-packages/_pytest/_code/__init__.py DELETED
@@ -1,26 +0,0 @@
1
- """Python inspection/code generation API."""
2
-
3
- from __future__ import annotations
4
-
5
- from .code import Code
6
- from .code import ExceptionInfo
7
- from .code import filter_traceback
8
- from .code import Frame
9
- from .code import getfslineno
10
- from .code import Traceback
11
- from .code import TracebackEntry
12
- from .source import getrawcode
13
- from .source import Source
14
-
15
-
16
- __all__ = [
17
- "Code",
18
- "ExceptionInfo",
19
- "Frame",
20
- "Source",
21
- "Traceback",
22
- "TracebackEntry",
23
- "filter_traceback",
24
- "getfslineno",
25
- "getrawcode",
26
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/lib/python3.12/site-packages/_pytest/_code/code.py DELETED
@@ -1,1632 +0,0 @@
1
- # mypy: allow-untyped-defs
2
- from __future__ import annotations
3
-
4
- import ast
5
- from collections.abc import Callable
6
- from collections.abc import Iterable
7
- from collections.abc import Mapping
8
- from collections.abc import Sequence
9
- import dataclasses
10
- import inspect
11
- from io import StringIO
12
- import os
13
- from pathlib import Path
14
- import re
15
- import sys
16
- from traceback import extract_tb
17
- from traceback import format_exception
18
- from traceback import format_exception_only
19
- from traceback import FrameSummary
20
- from types import CodeType
21
- from types import FrameType
22
- from types import TracebackType
23
- from typing import Any
24
- from typing import ClassVar
25
- from typing import Final
26
- from typing import final
27
- from typing import Generic
28
- from typing import Literal
29
- from typing import overload
30
- from typing import SupportsIndex
31
- from typing import TypeAlias
32
- from typing import TypeVar
33
-
34
- import pluggy
35
-
36
- import _pytest
37
- from _pytest._code.source import findsource
38
- from _pytest._code.source import getrawcode
39
- from _pytest._code.source import getstatementrange_ast
40
- from _pytest._code.source import Source
41
- from _pytest._io import TerminalWriter
42
- from _pytest._io.saferepr import safeformat
43
- from _pytest._io.saferepr import saferepr
44
- from _pytest.compat import get_real_func
45
- from _pytest.deprecated import check_ispytest
46
- from _pytest.pathlib import absolutepath
47
- from _pytest.pathlib import bestrelpath
48
-
49
-
50
- if sys.version_info < (3, 11):
51
- from exceptiongroup import BaseExceptionGroup
52
-
53
- TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
54
-
55
- EXCEPTION_OR_MORE = type[BaseException] | tuple[type[BaseException], ...]
56
-
57
-
58
- class Code:
59
- """Wrapper around Python code objects."""
60
-
61
- __slots__ = ("raw",)
62
-
63
- def __init__(self, obj: CodeType) -> None:
64
- self.raw = obj
65
-
66
- @classmethod
67
- def from_function(cls, obj: object) -> Code:
68
- return cls(getrawcode(obj))
69
-
70
- def __eq__(self, other):
71
- return self.raw == other.raw
72
-
73
- # Ignore type because of https://github.com/python/mypy/issues/4266.
74
- __hash__ = None # type: ignore
75
-
76
- @property
77
- def firstlineno(self) -> int:
78
- return self.raw.co_firstlineno - 1
79
-
80
- @property
81
- def name(self) -> str:
82
- return self.raw.co_name
83
-
84
- @property
85
- def path(self) -> Path | str:
86
- """Return a path object pointing to source code, or an ``str`` in
87
- case of ``OSError`` / non-existing file."""
88
- filename = inspect.getfile(self.raw)
89
- if not filename:
90
- return ""
91
- try:
92
- p = absolutepath(filename)
93
- # maybe don't try this checking
94
- if not p.exists():
95
- raise OSError("path check failed.")
96
- return p
97
- except OSError:
98
- # XXX maybe try harder like the weird logic
99
- # in the standard lib [linecache.updatecache] does?
100
- return filename
101
-
102
- @property
103
- def fullsource(self) -> Source | None:
104
- """Return a _pytest._code.Source object for the full source file of the code."""
105
- full, _ = findsource(self.raw)
106
- return full
107
-
108
- def source(self) -> Source:
109
- """Return a _pytest._code.Source object for the code object's source only."""
110
- # return source only for that part of code
111
- return Source(self.raw)
112
-
113
- def getargs(self, var: bool = False) -> tuple[str, ...]:
114
- """Return a tuple with the argument names for the code object.
115
-
116
- If 'var' is set True also return the names of the variable and
117
- keyword arguments when present.
118
- """
119
- # inspect.getargs merges positional and kwonly into a single list;
120
- # co_argcount is needed to exclude kwonly when var=False.
121
- args, varargs, varkw = inspect.getargs(self.raw)
122
- if not var:
123
- return tuple(args[: self.raw.co_argcount])
124
- result = list(args)
125
- if varargs is not None:
126
- result.append(varargs)
127
- if varkw is not None:
128
- result.append(varkw)
129
- return tuple(result)
130
-
131
-
132
- class Frame:
133
- """Wrapper around a Python frame holding f_locals and f_globals
134
- in which expressions can be evaluated."""
135
-
136
- __slots__ = ("raw",)
137
-
138
- def __init__(self, frame: FrameType) -> None:
139
- self.raw = frame
140
-
141
- @property
142
- def lineno(self) -> int:
143
- return self.raw.f_lineno - 1
144
-
145
- @property
146
- def f_globals(self) -> dict[str, Any]:
147
- return self.raw.f_globals
148
-
149
- @property
150
- def f_locals(self) -> dict[str, Any]:
151
- return self.raw.f_locals
152
-
153
- @property
154
- def code(self) -> Code:
155
- return Code(self.raw.f_code)
156
-
157
- @property
158
- def statement(self) -> Source:
159
- """Statement this frame is at."""
160
- if self.code.fullsource is None:
161
- return Source("")
162
- return self.code.fullsource.getstatement(self.lineno)
163
-
164
- def eval(self, code, **vars):
165
- """Evaluate 'code' in the frame.
166
-
167
- 'vars' are optional additional local variables.
168
-
169
- Returns the result of the evaluation.
170
- """
171
- f_locals = self.f_locals.copy()
172
- f_locals.update(vars)
173
- return eval(code, self.f_globals, f_locals)
174
-
175
- def repr(self, object: object) -> str:
176
- """Return a 'safe' (non-recursive, one-line) string repr for 'object'."""
177
- return saferepr(object)
178
-
179
- def getargs(self, var: bool = False):
180
- """Return a list of tuples (name, value) for all arguments.
181
-
182
- If 'var' is set True, also include the variable and keyword arguments
183
- when present.
184
- """
185
- retval = []
186
- for arg in self.code.getargs(var):
187
- try:
188
- retval.append((arg, self.f_locals[arg]))
189
- except KeyError:
190
- pass # this can occur when using Psyco
191
- return retval
192
-
193
-
194
- class TracebackEntry:
195
- """A single entry in a Traceback."""
196
-
197
- __slots__ = ("_rawentry", "_repr_style")
198
-
199
- def __init__(
200
- self,
201
- rawentry: TracebackType,
202
- repr_style: Literal["short", "long"] | None = None,
203
- ) -> None:
204
- self._rawentry: Final = rawentry
205
- self._repr_style: Final = repr_style
206
-
207
- def with_repr_style(
208
- self, repr_style: Literal["short", "long"] | None
209
- ) -> TracebackEntry:
210
- return TracebackEntry(self._rawentry, repr_style)
211
-
212
- @property
213
- def lineno(self) -> int:
214
- return self._rawentry.tb_lineno - 1
215
-
216
- def get_python_framesummary(self) -> FrameSummary:
217
- # Python's built-in traceback module implements all the nitty gritty
218
- # details to get column numbers of out frames.
219
- stack_summary = extract_tb(self._rawentry, limit=1)
220
- return stack_summary[0]
221
-
222
- # Column and end line numbers introduced in python 3.11
223
- if sys.version_info < (3, 11):
224
-
225
- @property
226
- def end_lineno_relative(self) -> int | None:
227
- return None
228
-
229
- @property
230
- def colno(self) -> int | None:
231
- return None
232
-
233
- @property
234
- def end_colno(self) -> int | None:
235
- return None
236
- else:
237
-
238
- @property
239
- def end_lineno_relative(self) -> int | None:
240
- frame_summary = self.get_python_framesummary()
241
- if frame_summary.end_lineno is None: # pragma: no cover
242
- return None
243
- return frame_summary.end_lineno - 1 - self.frame.code.firstlineno
244
-
245
- @property
246
- def colno(self) -> int | None:
247
- """Starting byte offset of the expression in the traceback entry."""
248
- return self.get_python_framesummary().colno
249
-
250
- @property
251
- def end_colno(self) -> int | None:
252
- """Ending byte offset of the expression in the traceback entry."""
253
- return self.get_python_framesummary().end_colno
254
-
255
- @property
256
- def frame(self) -> Frame:
257
- return Frame(self._rawentry.tb_frame)
258
-
259
- @property
260
- def relline(self) -> int:
261
- return self.lineno - self.frame.code.firstlineno
262
-
263
- def __repr__(self) -> str:
264
- return f"<TracebackEntry {self.frame.code.path}:{self.lineno + 1}>"
265
-
266
- @property
267
- def statement(self) -> Source:
268
- """_pytest._code.Source object for the current statement."""
269
- source = self.frame.code.fullsource
270
- assert source is not None
271
- return source.getstatement(self.lineno)
272
-
273
- @property
274
- def path(self) -> Path | str:
275
- """Path to the source code."""
276
- return self.frame.code.path
277
-
278
- @property
279
- def locals(self) -> dict[str, Any]:
280
- """Locals of underlying frame."""
281
- return self.frame.f_locals
282
-
283
- def getfirstlinesource(self) -> int:
284
- return self.frame.code.firstlineno
285
-
286
- def getsource(
287
- self, astcache: dict[str | Path, ast.AST] | None = None
288
- ) -> Source | None:
289
- """Return failing source code."""
290
- # we use the passed in astcache to not reparse asttrees
291
- # within exception info printing
292
- source = self.frame.code.fullsource
293
- if source is None:
294
- return None
295
- key = astnode = None
296
- if astcache is not None:
297
- key = self.frame.code.path
298
- if key is not None:
299
- astnode = astcache.get(key, None)
300
- start = self.getfirstlinesource()
301
- try:
302
- astnode, _, end = getstatementrange_ast(
303
- self.lineno, source, astnode=astnode
304
- )
305
- except SyntaxError:
306
- end = self.lineno + 1
307
- else:
308
- if key is not None and astcache is not None:
309
- astcache[key] = astnode
310
- return source[start:end]
311
-
312
- source = property(getsource)
313
-
314
- def ishidden(self, excinfo: ExceptionInfo[BaseException] | None) -> bool:
315
- """Return True if the current frame has a var __tracebackhide__
316
- resolving to True.
317
-
318
- If __tracebackhide__ is a callable, it gets called with the
319
- ExceptionInfo instance and can decide whether to hide the traceback.
320
-
321
- Mostly for internal use.
322
- """
323
- tbh: bool | Callable[[ExceptionInfo[BaseException] | None], bool] = False
324
- for maybe_ns_dct in (self.frame.f_locals, self.frame.f_globals):
325
- # in normal cases, f_locals and f_globals are dictionaries
326
- # however via `exec(...)` / `eval(...)` they can be other types
327
- # (even incorrect types!).
328
- # as such, we suppress all exceptions while accessing __tracebackhide__
329
- try:
330
- tbh = maybe_ns_dct["__tracebackhide__"]
331
- except Exception:
332
- pass
333
- else:
334
- break
335
- if tbh and callable(tbh):
336
- return tbh(excinfo)
337
- return tbh
338
-
339
- def __str__(self) -> str:
340
- name = self.frame.code.name
341
- try:
342
- line = str(self.statement).lstrip()
343
- except KeyboardInterrupt:
344
- raise
345
- except BaseException:
346
- line = "???"
347
- # This output does not quite match Python's repr for traceback entries,
348
- # but changing it to do so would break certain plugins. See
349
- # https://github.com/pytest-dev/pytest/pull/7535/ for details.
350
- return f" File '{self.path}':{self.lineno + 1} in {name}\n {line}\n"
351
-
352
- @property
353
- def name(self) -> str:
354
- """co_name of underlying code."""
355
- return self.frame.code.raw.co_name
356
-
357
-
358
- class Traceback(list[TracebackEntry]):
359
- """Traceback objects encapsulate and offer higher level access to Traceback entries."""
360
-
361
- def __init__(
362
- self,
363
- tb: TracebackType | Iterable[TracebackEntry],
364
- ) -> None:
365
- """Initialize from given python traceback object and ExceptionInfo."""
366
- if isinstance(tb, TracebackType):
367
-
368
- def f(cur: TracebackType) -> Iterable[TracebackEntry]:
369
- cur_: TracebackType | None = cur
370
- while cur_ is not None:
371
- yield TracebackEntry(cur_)
372
- cur_ = cur_.tb_next
373
-
374
- super().__init__(f(tb))
375
- else:
376
- super().__init__(tb)
377
-
378
- def cut(
379
- self,
380
- path: os.PathLike[str] | str | None = None,
381
- lineno: int | None = None,
382
- firstlineno: int | None = None,
383
- excludepath: os.PathLike[str] | None = None,
384
- ) -> Traceback:
385
- """Return a Traceback instance wrapping part of this Traceback.
386
-
387
- By providing any combination of path, lineno and firstlineno, the
388
- first frame to start the to-be-returned traceback is determined.
389
-
390
- This allows cutting the first part of a Traceback instance e.g.
391
- for formatting reasons (removing some uninteresting bits that deal
392
- with handling of the exception/traceback).
393
- """
394
- path_ = None if path is None else os.fspath(path)
395
- excludepath_ = None if excludepath is None else os.fspath(excludepath)
396
- for x in self:
397
- code = x.frame.code
398
- codepath = code.path
399
- if path is not None and str(codepath) != path_:
400
- continue
401
- if (
402
- excludepath is not None
403
- and isinstance(codepath, Path)
404
- and excludepath_ in (str(p) for p in codepath.parents) # type: ignore[operator]
405
- ):
406
- continue
407
- if lineno is not None and x.lineno != lineno:
408
- continue
409
- if firstlineno is not None and x.frame.code.firstlineno != firstlineno:
410
- continue
411
- return Traceback(x._rawentry)
412
- return self
413
-
414
- @overload
415
- def __getitem__(self, key: SupportsIndex) -> TracebackEntry: ...
416
-
417
- @overload
418
- def __getitem__(self, key: slice) -> Traceback: ...
419
-
420
- def __getitem__(self, key: SupportsIndex | slice) -> TracebackEntry | Traceback:
421
- if isinstance(key, slice):
422
- return self.__class__(super().__getitem__(key))
423
- else:
424
- return super().__getitem__(key)
425
-
426
- def filter(
427
- self,
428
- excinfo_or_fn: ExceptionInfo[BaseException] | Callable[[TracebackEntry], bool],
429
- /,
430
- ) -> Traceback:
431
- """Return a Traceback instance with certain items removed.
432
-
433
- If the filter is an `ExceptionInfo`, removes all the ``TracebackEntry``s
434
- which are hidden (see ishidden() above).
435
-
436
- Otherwise, the filter is a function that gets a single argument, a
437
- ``TracebackEntry`` instance, and should return True when the item should
438
- be added to the ``Traceback``, False when not.
439
- """
440
- if isinstance(excinfo_or_fn, ExceptionInfo):
441
- fn = lambda x: not x.ishidden(excinfo_or_fn) # noqa: E731
442
- else:
443
- fn = excinfo_or_fn
444
- return Traceback(filter(fn, self))
445
-
446
- def recursionindex(self) -> int | None:
447
- """Return the index of the frame/TracebackEntry where recursion originates if
448
- appropriate, None if no recursion occurred."""
449
- cache: dict[tuple[Any, int, int], list[dict[str, Any]]] = {}
450
- for i, entry in enumerate(self):
451
- # id for the code.raw is needed to work around
452
- # the strange metaprogramming in the decorator lib from pypi
453
- # which generates code objects that have hash/value equality
454
- # XXX needs a test
455
- key = entry.frame.code.path, id(entry.frame.code.raw), entry.lineno
456
- values = cache.setdefault(key, [])
457
- # Since Python 3.13 f_locals is a proxy, freeze it.
458
- loc = dict(entry.frame.f_locals)
459
- if values:
460
- for otherloc in values:
461
- if otherloc == loc:
462
- return i
463
- values.append(loc)
464
- return None
465
-
466
-
467
- def stringify_exception(
468
- exc: BaseException, include_subexception_msg: bool = True
469
- ) -> str:
470
- try:
471
- notes = getattr(exc, "__notes__", [])
472
- except KeyError:
473
- # Workaround for https://github.com/python/cpython/issues/98778 on
474
- # some 3.10 and 3.11 patch versions.
475
- HTTPError = getattr(sys.modules.get("urllib.error", None), "HTTPError", ())
476
- if sys.version_info < (3, 12) and isinstance(exc, HTTPError):
477
- notes = []
478
- else: # pragma: no cover
479
- # exception not related to above bug, reraise
480
- raise
481
- if not include_subexception_msg and isinstance(exc, BaseExceptionGroup):
482
- message = exc.message
483
- else:
484
- message = str(exc)
485
-
486
- return "\n".join(
487
- [
488
- message,
489
- *notes,
490
- ]
491
- )
492
-
493
-
494
- E = TypeVar("E", bound=BaseException, covariant=True)
495
-
496
-
497
- @final
498
- @dataclasses.dataclass
499
- class ExceptionInfo(Generic[E]):
500
- """Wraps sys.exc_info() objects and offers help for navigating the traceback."""
501
-
502
- _assert_start_repr: ClassVar = "AssertionError('assert "
503
-
504
- _excinfo: tuple[type[E], E, TracebackType] | None
505
- _striptext: str
506
- _traceback: Traceback | None
507
-
508
- def __init__(
509
- self,
510
- excinfo: tuple[type[E], E, TracebackType] | None,
511
- striptext: str = "",
512
- traceback: Traceback | None = None,
513
- *,
514
- _ispytest: bool = False,
515
- ) -> None:
516
- check_ispytest(_ispytest)
517
- self._excinfo = excinfo
518
- self._striptext = striptext
519
- self._traceback = traceback
520
-
521
- @classmethod
522
- def from_exception(
523
- cls,
524
- # Ignoring error: "Cannot use a covariant type variable as a parameter".
525
- # This is OK to ignore because this class is (conceptually) readonly.
526
- # See https://github.com/python/mypy/issues/7049.
527
- exception: E, # type: ignore[misc]
528
- exprinfo: str | None = None,
529
- ) -> ExceptionInfo[E]:
530
- """Return an ExceptionInfo for an existing exception.
531
-
532
- The exception must have a non-``None`` ``__traceback__`` attribute,
533
- otherwise this function fails with an assertion error. This means that
534
- the exception must have been raised, or added a traceback with the
535
- :py:meth:`~BaseException.with_traceback()` method.
536
-
537
- :param exprinfo:
538
- A text string helping to determine if we should strip
539
- ``AssertionError`` from the output. Defaults to the exception
540
- message/``__str__()``.
541
-
542
- .. versionadded:: 7.4
543
- """
544
- assert exception.__traceback__, (
545
- "Exceptions passed to ExcInfo.from_exception(...)"
546
- " must have a non-None __traceback__."
547
- )
548
- exc_info = (type(exception), exception, exception.__traceback__)
549
- return cls.from_exc_info(exc_info, exprinfo)
550
-
551
- @classmethod
552
- def from_exc_info(
553
- cls,
554
- exc_info: tuple[type[E], E, TracebackType],
555
- exprinfo: str | None = None,
556
- ) -> ExceptionInfo[E]:
557
- """Like :func:`from_exception`, but using old-style exc_info tuple."""
558
- _striptext = ""
559
- if exprinfo is None and isinstance(exc_info[1], AssertionError):
560
- exprinfo = getattr(exc_info[1], "msg", None)
561
- if exprinfo is None:
562
- exprinfo = saferepr(exc_info[1])
563
- if exprinfo and exprinfo.startswith(cls._assert_start_repr):
564
- _striptext = "AssertionError: "
565
-
566
- return cls(exc_info, _striptext, _ispytest=True)
567
-
568
- @classmethod
569
- def from_current(cls, exprinfo: str | None = None) -> ExceptionInfo[BaseException]:
570
- """Return an ExceptionInfo matching the current traceback.
571
-
572
- .. warning::
573
-
574
- Experimental API
575
-
576
- :param exprinfo:
577
- A text string helping to determine if we should strip
578
- ``AssertionError`` from the output. Defaults to the exception
579
- message/``__str__()``.
580
- """
581
- tup = sys.exc_info()
582
- assert tup[0] is not None, "no current exception"
583
- assert tup[1] is not None, "no current exception"
584
- assert tup[2] is not None, "no current exception"
585
- exc_info = (tup[0], tup[1], tup[2])
586
- return ExceptionInfo.from_exc_info(exc_info, exprinfo)
587
-
588
- @classmethod
589
- def for_later(cls) -> ExceptionInfo[E]:
590
- """Return an unfilled ExceptionInfo."""
591
- return cls(None, _ispytest=True)
592
-
593
- def fill_unfilled(self, exc_info: tuple[type[E], E, TracebackType]) -> None:
594
- """Fill an unfilled ExceptionInfo created with ``for_later()``."""
595
- assert self._excinfo is None, "ExceptionInfo was already filled"
596
- self._excinfo = exc_info
597
-
598
- @property
599
- def type(self) -> type[E]:
600
- """The exception class."""
601
- assert self._excinfo is not None, (
602
- ".type can only be used after the context manager exits"
603
- )
604
- return self._excinfo[0]
605
-
606
- @property
607
- def value(self) -> E:
608
- """The exception value."""
609
- assert self._excinfo is not None, (
610
- ".value can only be used after the context manager exits"
611
- )
612
- return self._excinfo[1]
613
-
614
- @property
615
- def tb(self) -> TracebackType:
616
- """The exception raw traceback."""
617
- assert self._excinfo is not None, (
618
- ".tb can only be used after the context manager exits"
619
- )
620
- return self._excinfo[2]
621
-
622
- @property
623
- def typename(self) -> str:
624
- """The type name of the exception."""
625
- assert self._excinfo is not None, (
626
- ".typename can only be used after the context manager exits"
627
- )
628
- return self.type.__name__
629
-
630
- @property
631
- def traceback(self) -> Traceback:
632
- """The traceback."""
633
- if self._traceback is None:
634
- self._traceback = Traceback(self.tb)
635
- return self._traceback
636
-
637
- @traceback.setter
638
- def traceback(self, value: Traceback) -> None:
639
- self._traceback = value
640
-
641
- def __repr__(self) -> str:
642
- if self._excinfo is None:
643
- return "<ExceptionInfo for raises contextmanager>"
644
- return f"<{self.__class__.__name__} {saferepr(self._excinfo[1])} tblen={len(self.traceback)}>"
645
-
646
- def exconly(self, tryshort: bool = False) -> str:
647
- """Return the exception as a string.
648
-
649
- This is usually a single line "<exception type>: <exception str>", but
650
- may also include additional lines for the exception notes, and detailed
651
- information for SyntaxError's.
652
-
653
- :param tryshort:
654
- If true, and the exception is an AssertionError, strip
655
- 'AssertionError: ' from the beginning.
656
- """
657
-
658
- def _get_single_subexc(
659
- eg: BaseExceptionGroup[BaseException],
660
- ) -> BaseException | None:
661
- if len(eg.exceptions) != 1:
662
- return None
663
- if isinstance(e := eg.exceptions[0], BaseExceptionGroup):
664
- return _get_single_subexc(e)
665
- return e
666
-
667
- if (
668
- tryshort
669
- and isinstance(self.value, BaseExceptionGroup)
670
- and (subexc := _get_single_subexc(self.value)) is not None
671
- ):
672
- return f"{subexc!r} [single exception in {type(self.value).__name__}]"
673
-
674
- lines = format_exception_only(self.value)
675
- # The lines already include line separators.
676
- text = "".join(lines)
677
- text = text.rstrip()
678
- if tryshort:
679
- if text.startswith(self._striptext):
680
- text = text[len(self._striptext) :]
681
- return text
682
-
683
- def errisinstance(self, exc: EXCEPTION_OR_MORE) -> bool:
684
- """Return True if the exception is an instance of exc.
685
-
686
- Consider using ``isinstance(excinfo.value, exc)`` instead.
687
- """
688
- return isinstance(self.value, exc)
689
-
690
- def _getreprcrash(self) -> ReprFileLocation | None:
691
- # Find last non-hidden traceback entry that led to the exception of the
692
- # traceback, or None if all hidden.
693
- for i in range(-1, -len(self.traceback) - 1, -1):
694
- entry = self.traceback[i]
695
- if not entry.ishidden(self):
696
- path, lineno = entry.frame.code.raw.co_filename, entry.lineno
697
- exconly = self.exconly(tryshort=True)
698
- return ReprFileLocation(path, lineno + 1, exconly)
699
- return None
700
-
701
- def getrepr(
702
- self,
703
- showlocals: bool = False,
704
- style: TracebackStyle = "long",
705
- abspath: bool = False,
706
- tbfilter: bool | Callable[[ExceptionInfo[BaseException]], Traceback] = True,
707
- funcargs: bool = False,
708
- truncate_locals: bool = True,
709
- truncate_args: bool = True,
710
- chain: bool = True,
711
- ) -> ReprExceptionInfo | ExceptionChainRepr:
712
- """Return str()able representation of this exception info.
713
-
714
- The formatting parameters are ineffective if ``style="native"``,
715
- since in this case the native formatting is used.
716
-
717
- :param bool showlocals:
718
- Show locals per traceback entry.
719
-
720
- :param str style:
721
- long|short|line|no|native|value traceback style.
722
-
723
- :param bool abspath:
724
- If paths should be changed to absolute or left unchanged.
725
-
726
- :param tbfilter:
727
- A filter for traceback entries.
728
-
729
- * If false, don't hide any entries.
730
- * If true, hide internal entries and entries that contain a local
731
- variable ``__tracebackhide__ = True``.
732
- * If a callable, delegates the filtering to the callable.
733
-
734
- :param bool funcargs:
735
- Show function arguments per traceback entry.
736
-
737
- :param bool truncate_locals:
738
- Whether to show a size-limited `repr()` of locals, or a full
739
- pretty-printing.
740
-
741
- :param bool truncate_args:
742
- Whether to show a size-limited truncated `repr()` of function
743
- arguments, or a full pretty-printing.
744
-
745
- :param bool chain:
746
- If chained exceptions should be shown.
747
-
748
- .. versionchanged:: 3.9
749
-
750
- Added the ``chain`` parameter.
751
- """
752
- if style == "native":
753
- return ReprExceptionInfo(
754
- reprtraceback=ReprTracebackNative(
755
- format_exception(
756
- self.type,
757
- self.value,
758
- self.traceback[0]._rawentry if self.traceback else None,
759
- )
760
- ),
761
- reprcrash=self._getreprcrash(),
762
- )
763
-
764
- fmt = ExceptionInfoFormatter(
765
- showlocals=showlocals,
766
- style=style,
767
- abspath=abspath,
768
- tbfilter=tbfilter,
769
- funcargs=funcargs,
770
- truncate_locals=truncate_locals,
771
- truncate_args=truncate_args,
772
- chain=chain,
773
- )
774
- return fmt.repr_excinfo(self)
775
-
776
- def match(self, regexp: str | re.Pattern[str]) -> Literal[True]:
777
- """Check whether the regular expression `regexp` matches the string
778
- representation of the exception using :func:`python:re.search`.
779
-
780
- If it matches `True` is returned, otherwise an `AssertionError` is raised.
781
- """
782
- __tracebackhide__ = True
783
- value = stringify_exception(self.value)
784
- msg = (
785
- f"Regex pattern did not match.\n"
786
- f" Expected regex: {regexp!r}\n"
787
- f" Actual message: {value!r}"
788
- )
789
- if regexp == value:
790
- msg += "\n Did you mean to `re.escape()` the regex?"
791
- assert re.search(regexp, value), msg
792
- # Return True to allow for "assert excinfo.match()".
793
- return True
794
-
795
- def _group_contains(
796
- self,
797
- exc_group: BaseExceptionGroup[BaseException],
798
- expected_exception: EXCEPTION_OR_MORE,
799
- match: str | re.Pattern[str] | None,
800
- target_depth: int | None = None,
801
- current_depth: int = 1,
802
- ) -> bool:
803
- """Return `True` if a `BaseExceptionGroup` contains a matching exception."""
804
- if (target_depth is not None) and (current_depth > target_depth):
805
- # already descended past the target depth
806
- return False
807
- for exc in exc_group.exceptions:
808
- if isinstance(exc, BaseExceptionGroup):
809
- if self._group_contains(
810
- exc, expected_exception, match, target_depth, current_depth + 1
811
- ):
812
- return True
813
- if (target_depth is not None) and (current_depth != target_depth):
814
- # not at the target depth, no match
815
- continue
816
- if not isinstance(exc, expected_exception):
817
- continue
818
- if match is not None:
819
- value = stringify_exception(exc)
820
- if not re.search(match, value):
821
- continue
822
- return True
823
- return False
824
-
825
- def group_contains(
826
- self,
827
- expected_exception: EXCEPTION_OR_MORE,
828
- *,
829
- match: str | re.Pattern[str] | None = None,
830
- depth: int | None = None,
831
- ) -> bool:
832
- """Check whether a captured exception group contains a matching exception.
833
-
834
- :param Type[BaseException] | Tuple[Type[BaseException]] expected_exception:
835
- The expected exception type, or a tuple if one of multiple possible
836
- exception types are expected.
837
-
838
- :param str | re.Pattern[str] | None match:
839
- If specified, a string containing a regular expression,
840
- or a regular expression object, that is tested against the string
841
- representation of the exception and its `PEP-678 <https://peps.python.org/pep-0678/>` `__notes__`
842
- using :func:`re.search`.
843
-
844
- To match a literal string that may contain :ref:`special characters
845
- <re-syntax>`, the pattern can first be escaped with :func:`re.escape`.
846
-
847
- :param Optional[int] depth:
848
- If `None`, will search for a matching exception at any nesting depth.
849
- If >= 1, will only match an exception if it's at the specified depth (depth = 1 being
850
- the exceptions contained within the topmost exception group).
851
-
852
- .. versionadded:: 8.0
853
-
854
- .. warning::
855
- This helper makes it easy to check for the presence of specific exceptions,
856
- but it is very bad for checking that the group does *not* contain
857
- *any other exceptions*.
858
- You should instead consider using :class:`pytest.RaisesGroup`
859
-
860
- """
861
- msg = "Captured exception is not an instance of `BaseExceptionGroup`"
862
- assert isinstance(self.value, BaseExceptionGroup), msg
863
- msg = "`depth` must be >= 1 if specified"
864
- assert (depth is None) or (depth >= 1), msg
865
- return self._group_contains(self.value, expected_exception, match, depth)
866
-
867
-
868
- # Type alias for the `tbfilter` setting:
869
- # bool: If True, it should be filtered using Traceback.filter()
870
- # callable: A callable that takes an ExceptionInfo and returns the filtered traceback.
871
- TracebackFilter: TypeAlias = bool | Callable[[ExceptionInfo[BaseException]], Traceback]
872
-
873
-
874
- @dataclasses.dataclass
875
- class ExceptionInfoFormatter:
876
- """Helper object to format ExceptionInfo's and individual exception parts
877
- into TerminalRepr's.
878
-
879
- See :func:`ExceptionInfo.getrepr` for parameters.
880
- """
881
-
882
- # for traceback entries
883
- flow_marker: ClassVar = ">"
884
- fail_marker: ClassVar = "E"
885
-
886
- showlocals: bool = False
887
- # Note: "native" is handled outside of ExceptionInfoFormatter.
888
- style: TracebackStyle = "long"
889
- abspath: bool = True
890
- tbfilter: TracebackFilter = True
891
- funcargs: bool = False
892
- truncate_locals: bool = True
893
- truncate_args: bool = True
894
- chain: bool = True
895
-
896
- astcache: dict[str | Path, ast.AST] = dataclasses.field(
897
- default_factory=dict, init=False, repr=False
898
- )
899
-
900
- def _getindent(self, source: Source) -> int:
901
- # Figure out indent for the given source.
902
- try:
903
- s = str(source.getstatement(len(source) - 1))
904
- except KeyboardInterrupt:
905
- raise
906
- except BaseException:
907
- try:
908
- s = str(source[-1])
909
- except KeyboardInterrupt:
910
- raise
911
- except BaseException:
912
- return 0
913
- return 4 + (len(s) - len(s.lstrip()))
914
-
915
- def _getentrysource(self, entry: TracebackEntry) -> Source | None:
916
- source = entry.getsource(self.astcache)
917
- if source is not None:
918
- source = source.deindent()
919
- return source
920
-
921
- def repr_args(self, entry: TracebackEntry) -> ReprFuncArgs | None:
922
- if self.funcargs:
923
- args = []
924
- for argname, argvalue in entry.frame.getargs(var=True):
925
- if self.truncate_args:
926
- str_repr = saferepr(argvalue)
927
- else:
928
- str_repr = saferepr(argvalue, maxsize=None)
929
- args.append((argname, str_repr))
930
- return ReprFuncArgs(args)
931
- return None
932
-
933
- def get_source(
934
- self,
935
- source: Source | None,
936
- line_index: int = -1,
937
- excinfo: ExceptionInfo[BaseException] | None = None,
938
- short: bool = False,
939
- end_line_index: int | None = None,
940
- colno: int | None = None,
941
- end_colno: int | None = None,
942
- ) -> list[str]:
943
- """Return formatted and marked up source lines."""
944
- lines = []
945
- if source is not None and line_index < 0:
946
- line_index += len(source)
947
- if source is None or line_index >= len(source.lines) or line_index < 0:
948
- # `line_index` could still be outside `range(len(source.lines))` if
949
- # we're processing AST with pathological position attributes.
950
- source = Source("???")
951
- line_index = 0
952
- space_prefix = " "
953
- if short:
954
- lines.append(space_prefix + source.lines[line_index].strip())
955
- lines.extend(
956
- self.get_highlight_arrows_for_line(
957
- raw_line=source.raw_lines[line_index],
958
- line=source.lines[line_index].strip(),
959
- lineno=line_index,
960
- end_lineno=end_line_index,
961
- colno=colno,
962
- end_colno=end_colno,
963
- )
964
- )
965
- else:
966
- for line in source.lines[:line_index]:
967
- lines.append(space_prefix + line)
968
- lines.append(self.flow_marker + " " + source.lines[line_index])
969
- lines.extend(
970
- self.get_highlight_arrows_for_line(
971
- raw_line=source.raw_lines[line_index],
972
- line=source.lines[line_index],
973
- lineno=line_index,
974
- end_lineno=end_line_index,
975
- colno=colno,
976
- end_colno=end_colno,
977
- )
978
- )
979
- for line in source.lines[line_index + 1 :]:
980
- lines.append(space_prefix + line)
981
- if excinfo is not None:
982
- indent = 4 if short else self._getindent(source)
983
- lines.extend(self.get_exconly(excinfo, indent=indent, markall=True))
984
- return lines
985
-
986
- def get_highlight_arrows_for_line(
987
- self,
988
- line: str,
989
- raw_line: str,
990
- lineno: int | None,
991
- end_lineno: int | None,
992
- colno: int | None,
993
- end_colno: int | None,
994
- ) -> list[str]:
995
- """Return characters highlighting a source line.
996
-
997
- Example with colno and end_colno pointing to the bar expression:
998
- "foo() + bar()"
999
- returns " ^^^^^"
1000
- """
1001
- if lineno != end_lineno:
1002
- # Don't handle expressions that span multiple lines.
1003
- return []
1004
- if colno is None or end_colno is None:
1005
- # Can't do anything without column information.
1006
- return []
1007
-
1008
- num_stripped_chars = len(raw_line) - len(line)
1009
-
1010
- start_char_offset = _byte_offset_to_character_offset(raw_line, colno)
1011
- end_char_offset = _byte_offset_to_character_offset(raw_line, end_colno)
1012
- num_carets = end_char_offset - start_char_offset
1013
- # If the highlight would span the whole line, it is redundant, don't
1014
- # show it.
1015
- if num_carets >= len(line.strip()):
1016
- return []
1017
-
1018
- highlights = " "
1019
- highlights += " " * (start_char_offset - num_stripped_chars + 1)
1020
- highlights += "^" * num_carets
1021
- return [highlights]
1022
-
1023
- def get_exconly(
1024
- self,
1025
- excinfo: ExceptionInfo[BaseException],
1026
- indent: int = 4,
1027
- markall: bool = False,
1028
- ) -> list[str]:
1029
- lines = []
1030
- indentstr = " " * indent
1031
- # Get the real exception information out.
1032
- exlines = excinfo.exconly(tryshort=True).split("\n")
1033
- failindent = self.fail_marker + indentstr[1:]
1034
- for line in exlines:
1035
- lines.append(failindent + line)
1036
- if not markall:
1037
- failindent = indentstr
1038
- return lines
1039
-
1040
- def repr_locals(self, locals: Mapping[str, object]) -> ReprLocals | None:
1041
- if self.showlocals:
1042
- lines = []
1043
- # Variables starting with `@` are helpers injected by assertion
1044
- # rewriting, not user variables, so hide them.
1045
- keys = [loc for loc in locals if loc[0] != "@"]
1046
- keys.sort()
1047
- for name in keys:
1048
- value = locals[name]
1049
- if name == "__builtins__":
1050
- lines.append("__builtins__ = <builtins>")
1051
- else:
1052
- # This formatting could all be handled by the
1053
- # _repr() function, which is only reprlib.Repr in
1054
- # disguise, so is very configurable.
1055
- if self.truncate_locals:
1056
- str_repr = saferepr(value)
1057
- else:
1058
- str_repr = safeformat(value)
1059
- # if len(str_repr) < 70 or not isinstance(value, (list, tuple, dict)):
1060
- lines.append(f"{name:<10} = {str_repr}")
1061
- # else:
1062
- # self._line("%-10s =\\" % (name,))
1063
- # # XXX
1064
- # pprint.pprint(value, stream=self.excinfowriter)
1065
- return ReprLocals(lines)
1066
- return None
1067
-
1068
- def repr_traceback_entry(
1069
- self,
1070
- entry: TracebackEntry | None,
1071
- excinfo: ExceptionInfo[BaseException] | None = None,
1072
- ) -> ReprEntry:
1073
- lines: list[str] = []
1074
- style = (
1075
- entry._repr_style
1076
- if entry is not None and entry._repr_style is not None
1077
- else self.style
1078
- )
1079
- if style in ("short", "long") and entry is not None:
1080
- source = self._getentrysource(entry)
1081
- if source is None:
1082
- source = Source("???")
1083
- line_index = 0
1084
- end_line_index, colno, end_colno = None, None, None
1085
- else:
1086
- line_index = entry.relline
1087
- end_line_index = entry.end_lineno_relative
1088
- colno = entry.colno
1089
- end_colno = entry.end_colno
1090
- short = style == "short"
1091
- reprargs = self.repr_args(entry) if not short else None
1092
- s = self.get_source(
1093
- source=source,
1094
- line_index=line_index,
1095
- excinfo=excinfo,
1096
- short=short,
1097
- end_line_index=end_line_index,
1098
- colno=colno,
1099
- end_colno=end_colno,
1100
- )
1101
- lines.extend(s)
1102
- if short:
1103
- message = f"in {entry.name}"
1104
- else:
1105
- message = (excinfo and excinfo.typename) or ""
1106
- entry_path = entry.path
1107
- path = self._makepath(entry_path)
1108
- reprfileloc = ReprFileLocation(path, entry.lineno + 1, message)
1109
- localsrepr = self.repr_locals(entry.locals)
1110
- return ReprEntry(lines, reprargs, localsrepr, reprfileloc, style)
1111
- elif style == "value":
1112
- if excinfo:
1113
- lines.extend(str(excinfo.value).split("\n"))
1114
- return ReprEntry(lines, None, None, None, style)
1115
- else:
1116
- if excinfo:
1117
- lines.extend(self.get_exconly(excinfo, indent=4))
1118
- return ReprEntry(lines, None, None, None, style)
1119
-
1120
- def _makepath(self, path: Path | str) -> str:
1121
- if not self.abspath and isinstance(path, Path):
1122
- try:
1123
- np = bestrelpath(Path.cwd(), path)
1124
- except OSError:
1125
- return str(path)
1126
- if len(np) < len(str(path)):
1127
- return np
1128
- return str(path)
1129
-
1130
- def repr_traceback(self, excinfo: ExceptionInfo[BaseException]) -> ReprTraceback:
1131
- traceback = filter_excinfo_traceback(self.tbfilter, excinfo)
1132
-
1133
- if isinstance(excinfo.value, RecursionError):
1134
- traceback, extraline = self._truncate_recursive_traceback(traceback)
1135
- else:
1136
- extraline = None
1137
-
1138
- if not traceback:
1139
- if extraline is None:
1140
- extraline = "All traceback entries are hidden. Pass `--full-trace` to see hidden and internal frames."
1141
- entries = [self.repr_traceback_entry(None, excinfo)]
1142
- return ReprTraceback(entries, extraline, style=self.style)
1143
-
1144
- last = traceback[-1]
1145
- if self.style == "value":
1146
- entries = [self.repr_traceback_entry(last, excinfo)]
1147
- return ReprTraceback(entries, None, style=self.style)
1148
-
1149
- entries = [
1150
- self.repr_traceback_entry(entry, excinfo if last == entry else None)
1151
- for entry in traceback
1152
- ]
1153
- return ReprTraceback(entries, extraline, style=self.style)
1154
-
1155
- def _truncate_recursive_traceback(
1156
- self, traceback: Traceback
1157
- ) -> tuple[Traceback, str | None]:
1158
- """Truncate the given recursive traceback trying to find the starting
1159
- point of the recursion.
1160
-
1161
- The detection is done by going through each traceback entry and
1162
- finding the point in which the locals of the frame are equal to the
1163
- locals of a previous frame (see ``recursionindex()``).
1164
-
1165
- Handle the situation where the recursion process might raise an
1166
- exception (for example comparing numpy arrays using equality raises a
1167
- TypeError), in which case we do our best to warn the user of the
1168
- error and show a limited traceback.
1169
- """
1170
- try:
1171
- recursionindex = traceback.recursionindex()
1172
- except Exception as e:
1173
- max_frames = 10
1174
- extraline: str | None = (
1175
- "!!! Recursion error detected, but an error occurred locating the origin of recursion.\n"
1176
- " The following exception happened when comparing locals in the stack frame:\n"
1177
- f" {type(e).__name__}: {e!s}\n"
1178
- f" Displaying first and last {max_frames} stack frames out of {len(traceback)}."
1179
- )
1180
- # Type ignored because adding two instances of a List subtype
1181
- # currently incorrectly has type List instead of the subtype.
1182
- traceback = traceback[:max_frames] + traceback[-max_frames:] # type: ignore
1183
- else:
1184
- if recursionindex is not None:
1185
- extraline = "!!! Recursion detected (same locals & position)"
1186
- traceback = traceback[: recursionindex + 1]
1187
- else:
1188
- extraline = None
1189
-
1190
- return traceback, extraline
1191
-
1192
- def repr_excinfo(self, excinfo: ExceptionInfo[BaseException]) -> ExceptionChainRepr:
1193
- repr_chain: list[tuple[ReprTraceback, ReprFileLocation | None, str | None]] = []
1194
- e: BaseException | None = excinfo.value
1195
- excinfo_: ExceptionInfo[BaseException] | None = excinfo
1196
- description = None
1197
- seen: set[int] = set()
1198
- while e is not None and id(e) not in seen:
1199
- seen.add(id(e))
1200
-
1201
- if excinfo_:
1202
- # Fall back to native traceback as a temporary workaround until
1203
- # full support for exception groups added to ExceptionInfo.
1204
- # See https://github.com/pytest-dev/pytest/issues/9159
1205
- reprtraceback: ReprTraceback | ReprTracebackNative
1206
- if isinstance(e, BaseExceptionGroup):
1207
- # don't filter any sub-exceptions since they shouldn't have any internal frames
1208
- traceback = filter_excinfo_traceback(self.tbfilter, excinfo)
1209
- extraline = (
1210
- "All traceback entries are hidden. Pass `--full-trace` to see hidden and internal frames."
1211
- if not traceback
1212
- else None
1213
- )
1214
- reprtraceback = ReprTracebackNative(
1215
- format_exception(
1216
- type(excinfo.value),
1217
- excinfo.value,
1218
- traceback[0]._rawentry if traceback else None,
1219
- ),
1220
- extraline=extraline,
1221
- )
1222
-
1223
- else:
1224
- reprtraceback = self.repr_traceback(excinfo_)
1225
- reprcrash = excinfo_._getreprcrash()
1226
- else:
1227
- # Fallback to native repr if the exception doesn't have a traceback:
1228
- # ExceptionInfo objects require a full traceback to work.
1229
- reprtraceback = ReprTracebackNative(format_exception(type(e), e, None))
1230
- reprcrash = None
1231
- repr_chain.append((reprtraceback, reprcrash, description))
1232
-
1233
- if e.__cause__ is not None and self.chain:
1234
- e = e.__cause__
1235
- excinfo_ = ExceptionInfo.from_exception(e) if e.__traceback__ else None
1236
- description = "The above exception was the direct cause of the following exception:"
1237
- elif (
1238
- e.__context__ is not None and not e.__suppress_context__ and self.chain
1239
- ):
1240
- e = e.__context__
1241
- excinfo_ = ExceptionInfo.from_exception(e) if e.__traceback__ else None
1242
- description = "During handling of the above exception, another exception occurred:"
1243
- else:
1244
- e = None
1245
- repr_chain.reverse()
1246
- return ExceptionChainRepr(repr_chain)
1247
-
1248
-
1249
- @dataclasses.dataclass(eq=False)
1250
- class TerminalRepr:
1251
- """Base class for terminal representations -- pieces of data that display
1252
- themselves to a terminal."""
1253
-
1254
- def __str__(self) -> str:
1255
- # FYI this is called from pytest-xdist's serialization of exception
1256
- # information.
1257
- io = StringIO()
1258
- tw = TerminalWriter(file=io)
1259
- self.toterminal(tw)
1260
- return io.getvalue().strip()
1261
-
1262
- def __repr__(self) -> str:
1263
- return f"<{self.__class__} instance at {id(self):0x}>"
1264
-
1265
- def toterminal(self, tw: TerminalWriter) -> None:
1266
- raise NotImplementedError()
1267
-
1268
-
1269
- @dataclasses.dataclass(eq=False)
1270
- class ExceptionRepr(TerminalRepr):
1271
- """Base class for exception terminal representations.
1272
-
1273
- The representation generally contains:
1274
- - The exception traceback (`reprtraceback`)
1275
- - The exception message and location (`reprcrash`)
1276
- - Separated, titled sections with additional data (pytest core doesn't use
1277
- this currently).
1278
- """
1279
-
1280
- reprtraceback: ReprTraceback
1281
- reprcrash: ReprFileLocation | None
1282
- sections: list[tuple[str, str, str]] = dataclasses.field(
1283
- init=False, default_factory=list
1284
- )
1285
-
1286
- def addsection(self, name: str, content: str, sep: str = "-") -> None:
1287
- self.sections.append((name, content, sep))
1288
-
1289
- def toterminal(self, tw: TerminalWriter) -> None:
1290
- for name, content, sep in self.sections:
1291
- tw.sep(sep, name)
1292
- tw.line(content)
1293
-
1294
-
1295
- @dataclasses.dataclass(eq=False)
1296
- class ExceptionChainRepr(ExceptionRepr):
1297
- """A chain of exceptions, separated by descriptions (e.g. "The above
1298
- exception was the direct cause of the following exception")."""
1299
-
1300
- chain: Sequence[tuple[ReprTraceback, ReprFileLocation | None, str | None]]
1301
-
1302
- def __init__(
1303
- self,
1304
- chain: Sequence[tuple[ReprTraceback, ReprFileLocation | None, str | None]],
1305
- ) -> None:
1306
- # reprcrash and reprtraceback of the outermost (the newest) exception
1307
- # in the chain.
1308
- super().__init__(
1309
- reprtraceback=chain[-1][0],
1310
- reprcrash=chain[-1][1],
1311
- )
1312
- self.chain = chain
1313
-
1314
- def toterminal(self, tw: TerminalWriter) -> None:
1315
- for reprtraceback, reprcrash, description in self.chain:
1316
- reprtraceback.toterminal(tw)
1317
- if description is not None:
1318
- tw.line("")
1319
- tw.line(description, yellow=True)
1320
- super().toterminal(tw)
1321
-
1322
-
1323
- @dataclasses.dataclass(eq=False)
1324
- class ReprExceptionInfo(ExceptionRepr):
1325
- """A single exception with optional extra details (function arguments,
1326
- function locals, file location) and possible extra line and sections emitted
1327
- at the end."""
1328
-
1329
- def toterminal(self, tw: TerminalWriter) -> None:
1330
- self.reprtraceback.toterminal(tw)
1331
- super().toterminal(tw)
1332
-
1333
-
1334
- @dataclasses.dataclass(eq=False)
1335
- class ReprTraceback(TerminalRepr):
1336
- """A traceback with optional extra details (function arguments, function
1337
- locals, file location) and possible extra line emitted at the end."""
1338
-
1339
- reprentries: Sequence[ReprEntry | ReprEntryNative]
1340
- extraline: str | None
1341
- style: TracebackStyle
1342
-
1343
- entrysep: ClassVar = "_ "
1344
-
1345
- def toterminal(self, tw: TerminalWriter) -> None:
1346
- # The entries might have different styles.
1347
- for i, entry in enumerate(self.reprentries):
1348
- if entry.style == "long":
1349
- tw.line("")
1350
- entry.toterminal(tw)
1351
- if i < len(self.reprentries) - 1:
1352
- next_entry = self.reprentries[i + 1]
1353
- if entry.style == "long" or (
1354
- entry.style == "short" and next_entry.style == "long"
1355
- ):
1356
- tw.sep(self.entrysep)
1357
-
1358
- if self.extraline:
1359
- tw.line(self.extraline)
1360
-
1361
-
1362
- class ReprTracebackNative(ReprTraceback):
1363
- """A traceback in native style.
1364
-
1365
- The lines are emitted as is; uses a single entry for the entire native
1366
- traceback.
1367
- """
1368
-
1369
- def __init__(self, tblines: Sequence[str], *, extraline: str | None = None) -> None:
1370
- self.reprentries = [ReprEntryNative(tblines)]
1371
- self.extraline = extraline
1372
- self.style = "native"
1373
-
1374
-
1375
- @dataclasses.dataclass(eq=False)
1376
- class ReprEntryNative(TerminalRepr):
1377
- """An entry in a traceback in native style.
1378
-
1379
- Emits the lines as is. The lines are assumed to include the line separators.
1380
-
1381
- [Note that we currently use a single "entry" for the entire native
1382
- traceback, so this is a bit misleading, but there's no point trying to parse
1383
- or split a native traceback.]
1384
- """
1385
-
1386
- lines: Sequence[str]
1387
-
1388
- style: ClassVar[TracebackStyle] = "native"
1389
-
1390
- def toterminal(self, tw: TerminalWriter) -> None:
1391
- tw.write("".join(self.lines))
1392
-
1393
-
1394
- @dataclasses.dataclass(eq=False)
1395
- class ReprEntry(TerminalRepr):
1396
- """An entry in a traceback with possible extra details (function arguments,
1397
- function locals, source snippet, function's file and line)."""
1398
-
1399
- lines: Sequence[str]
1400
- reprfuncargs: ReprFuncArgs | None
1401
- reprlocals: ReprLocals | None
1402
- reprfileloc: ReprFileLocation | None
1403
- style: TracebackStyle
1404
-
1405
- def _write_entry_lines(self, tw: TerminalWriter) -> None:
1406
- """Write the source code portions of a list of traceback entries with syntax highlighting.
1407
-
1408
- Usually entries are lines like these:
1409
-
1410
- " x = 1"
1411
- "> assert x == 2"
1412
- "E assert 1 == 2"
1413
-
1414
- This function takes care of rendering the "source" portions of it (the lines without
1415
- the "E" prefix) using syntax highlighting, taking care to not highlighting the ">"
1416
- character, as doing so might break line continuations.
1417
- """
1418
- if not self.lines:
1419
- return
1420
-
1421
- if self.style == "value":
1422
- # Using tw.write instead of tw.line for testing purposes due to TWMock implementation;
1423
- # lines written with TWMock.line and TWMock._write_source cannot be distinguished
1424
- # from each other, whereas lines written with TWMock.write are marked with TWMock.WRITE
1425
- for line in self.lines:
1426
- tw.write(line)
1427
- tw.write("\n")
1428
- return
1429
-
1430
- # separate indents and source lines that are not failures: we want to
1431
- # highlight the code but not the indentation, which may contain markers
1432
- # such as "> assert 0"
1433
- fail_marker = f"{ExceptionInfoFormatter.fail_marker} "
1434
- indent_size = len(fail_marker)
1435
- indents: list[str] = []
1436
- source_lines: list[str] = []
1437
- failure_lines: list[str] = []
1438
- for index, line in enumerate(self.lines):
1439
- is_failure_line = line.startswith(fail_marker)
1440
- if is_failure_line:
1441
- # from this point on all lines are considered part of the failure
1442
- failure_lines.extend(self.lines[index:])
1443
- break
1444
- else:
1445
- indents.append(line[:indent_size])
1446
- source_lines.append(line[indent_size:])
1447
-
1448
- tw._write_source(source_lines, indents)
1449
-
1450
- # failure lines are always completely red and bold
1451
- for line in failure_lines:
1452
- tw.line(line, bold=True, red=True)
1453
-
1454
- def toterminal(self, tw: TerminalWriter) -> None:
1455
- if self.style == "short":
1456
- if self.reprfileloc:
1457
- self.reprfileloc.toterminal(tw)
1458
- self._write_entry_lines(tw)
1459
- if self.reprlocals:
1460
- self.reprlocals.toterminal(tw, indent=" " * 8)
1461
- return
1462
-
1463
- if self.reprfuncargs:
1464
- self.reprfuncargs.toterminal(tw)
1465
-
1466
- self._write_entry_lines(tw)
1467
-
1468
- if self.reprlocals:
1469
- tw.line("")
1470
- self.reprlocals.toterminal(tw)
1471
- if self.reprfileloc:
1472
- if self.lines:
1473
- tw.line("")
1474
- self.reprfileloc.toterminal(tw)
1475
-
1476
- def __str__(self) -> str:
1477
- return "{}\n{}\n{}".format(
1478
- "\n".join(self.lines), self.reprlocals, self.reprfileloc
1479
- )
1480
-
1481
-
1482
- @dataclasses.dataclass(eq=False)
1483
- class ReprFileLocation(TerminalRepr):
1484
- """A message at a file location, using the `<path>:<lineno>: <message>`
1485
- format that most editors understand.
1486
-
1487
- Only the first line of the message is emitted.
1488
- """
1489
-
1490
- path: str
1491
- lineno: int
1492
- message: str
1493
-
1494
- def __post_init__(self) -> None:
1495
- self.path = str(self.path)
1496
-
1497
- def toterminal(self, tw: TerminalWriter) -> None:
1498
- msg = self.message
1499
- i = msg.find("\n")
1500
- if i != -1:
1501
- msg = msg[:i]
1502
- tw.write(self.path, bold=True, red=True)
1503
- tw.line(f":{self.lineno}: {msg}")
1504
-
1505
-
1506
- @dataclasses.dataclass(eq=False)
1507
- class ReprLocals(TerminalRepr):
1508
- """Function local variables (pre-formatted)."""
1509
-
1510
- lines: Sequence[str]
1511
-
1512
- def toterminal(self, tw: TerminalWriter, indent: str = "") -> None:
1513
- for line in self.lines:
1514
- tw.line(indent + line)
1515
-
1516
-
1517
- @dataclasses.dataclass(eq=False)
1518
- class ReprFuncArgs(TerminalRepr):
1519
- """Function arguments - name = value, comma separated."""
1520
-
1521
- args: Sequence[tuple[str, object]]
1522
-
1523
- def toterminal(self, tw: TerminalWriter) -> None:
1524
- if self.args:
1525
- linesofar = ""
1526
- for name, value in self.args:
1527
- ns = f"{name} = {value}"
1528
- if len(ns) + len(linesofar) + 2 > tw.fullwidth:
1529
- if linesofar:
1530
- tw.line(linesofar)
1531
- linesofar = ns
1532
- else:
1533
- if linesofar:
1534
- linesofar += ", " + ns
1535
- else:
1536
- linesofar = ns
1537
- if linesofar:
1538
- tw.line(linesofar)
1539
- tw.line("")
1540
-
1541
-
1542
- def getfslineno(obj: object) -> tuple[str | Path, int]:
1543
- """Return source location (path, lineno) for the given object.
1544
-
1545
- If the source cannot be determined return ("", -1).
1546
-
1547
- The line number is 0-based.
1548
- """
1549
- # xxx let decorators etc specify a sane ordering
1550
- # NOTE: this used to be done in _pytest.compat.getfslineno, initially added
1551
- # in 6ec13a2b9. It ("place_as") appears to be something very custom.
1552
- obj = get_real_func(obj)
1553
- if hasattr(obj, "place_as"):
1554
- obj = obj.place_as
1555
-
1556
- try:
1557
- code = Code.from_function(obj)
1558
- except TypeError:
1559
- try:
1560
- fn = inspect.getsourcefile(obj) or inspect.getfile(obj) # type: ignore[arg-type]
1561
- except TypeError:
1562
- return "", -1
1563
-
1564
- fspath = (fn and absolutepath(fn)) or ""
1565
- lineno = -1
1566
- if fspath:
1567
- try:
1568
- _, lineno = findsource(obj)
1569
- except OSError:
1570
- pass
1571
- return fspath, lineno
1572
-
1573
- return code.path, code.firstlineno
1574
-
1575
-
1576
- def _byte_offset_to_character_offset(str, offset):
1577
- """Converts a byte based offset in a string to a code-point."""
1578
- as_utf8 = str.encode("utf-8")
1579
- return len(as_utf8[:offset].decode("utf-8", errors="replace"))
1580
-
1581
-
1582
- # Relative paths that we use to filter traceback entries from appearing to the user;
1583
- # see filter_traceback.
1584
- # note: if we need to add more paths than what we have now we should probably use a list
1585
- # for better maintenance.
1586
-
1587
- _PLUGGY_DIR = Path(pluggy.__file__.rstrip("oc"))
1588
- # pluggy is either a package or a single module depending on the version
1589
- if _PLUGGY_DIR.name == "__init__.py":
1590
- _PLUGGY_DIR = _PLUGGY_DIR.parent
1591
- _PYTEST_DIR = Path(_pytest.__file__).parent
1592
-
1593
-
1594
- def filter_traceback(entry: TracebackEntry) -> bool:
1595
- """Return True if a TracebackEntry instance should be included in tracebacks.
1596
-
1597
- We hide traceback entries of:
1598
-
1599
- * dynamically generated code (no code to show up for it);
1600
- * internal traceback from pytest or its internal libraries, py and pluggy.
1601
- """
1602
- # entry.path might sometimes return a str object when the entry
1603
- # points to dynamically generated code.
1604
- # See https://bitbucket.org/pytest-dev/py/issues/71.
1605
- raw_filename = entry.frame.code.raw.co_filename
1606
- is_generated = "<" in raw_filename and ">" in raw_filename
1607
- if is_generated:
1608
- return False
1609
-
1610
- # entry.path might point to a non-existing file, in which case it will
1611
- # also return a str object. See #1133.
1612
- p = Path(entry.path)
1613
-
1614
- parents = p.parents
1615
- if _PLUGGY_DIR in parents:
1616
- return False
1617
- if _PYTEST_DIR in parents:
1618
- return False
1619
-
1620
- return True
1621
-
1622
-
1623
- def filter_excinfo_traceback(
1624
- tbfilter: TracebackFilter, excinfo: ExceptionInfo[BaseException]
1625
- ) -> Traceback:
1626
- """Filter the exception traceback in ``excinfo`` according to ``tbfilter``."""
1627
- if callable(tbfilter):
1628
- return tbfilter(excinfo)
1629
- elif tbfilter:
1630
- return excinfo.traceback.filter(excinfo)
1631
- else:
1632
- return excinfo.traceback
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/lib/python3.12/site-packages/_pytest/_code/source.py DELETED
@@ -1,228 +0,0 @@
1
- # mypy: allow-untyped-defs
2
- from __future__ import annotations
3
-
4
- import ast
5
- from bisect import bisect_right
6
- from collections.abc import Iterable
7
- from collections.abc import Iterator
8
- import inspect
9
- import textwrap
10
- import tokenize
11
- import types
12
- from typing import overload
13
- import warnings
14
-
15
-
16
- class Source:
17
- """An immutable object holding a source code fragment.
18
-
19
- When using Source(...), the source lines are deindented.
20
- """
21
-
22
- def __init__(self, obj: object = None) -> None:
23
- if not obj:
24
- self.lines: list[str] = []
25
- self.raw_lines: list[str] = []
26
- elif isinstance(obj, Source):
27
- self.lines = obj.lines
28
- self.raw_lines = obj.raw_lines
29
- elif isinstance(obj, tuple | list):
30
- self.lines = deindent(x.rstrip("\n") for x in obj)
31
- self.raw_lines = list(x.rstrip("\n") for x in obj)
32
- elif isinstance(obj, str):
33
- self.lines = deindent(obj.split("\n"))
34
- self.raw_lines = obj.split("\n")
35
- else:
36
- try:
37
- rawcode = getrawcode(obj)
38
- src = inspect.getsource(rawcode)
39
- except TypeError:
40
- src = inspect.getsource(obj) # type: ignore[arg-type]
41
- self.lines = deindent(src.split("\n"))
42
- self.raw_lines = src.split("\n")
43
-
44
- def __eq__(self, other: object) -> bool:
45
- if not isinstance(other, Source):
46
- return NotImplemented
47
- return self.lines == other.lines
48
-
49
- # Ignore type because of https://github.com/python/mypy/issues/4266.
50
- __hash__ = None # type: ignore
51
-
52
- @overload
53
- def __getitem__(self, key: int) -> str: ...
54
-
55
- @overload
56
- def __getitem__(self, key: slice) -> Source: ...
57
-
58
- def __getitem__(self, key: int | slice) -> str | Source:
59
- if isinstance(key, int):
60
- return self.lines[key]
61
- else:
62
- if key.step not in (None, 1):
63
- raise IndexError("cannot slice a Source with a step")
64
- newsource = Source()
65
- newsource.lines = self.lines[key.start : key.stop]
66
- newsource.raw_lines = self.raw_lines[key.start : key.stop]
67
- return newsource
68
-
69
- def __iter__(self) -> Iterator[str]:
70
- return iter(self.lines)
71
-
72
- def __len__(self) -> int:
73
- return len(self.lines)
74
-
75
- def strip(self) -> Source:
76
- """Return new Source object with trailing and leading blank lines removed."""
77
- start, end = 0, len(self)
78
- while start < end and not self.lines[start].strip():
79
- start += 1
80
- while end > start and not self.lines[end - 1].strip():
81
- end -= 1
82
- source = Source()
83
- source.raw_lines = self.raw_lines
84
- source.lines[:] = self.lines[start:end]
85
- return source
86
-
87
- def indent(self, indent: str = " " * 4) -> Source:
88
- """Return a copy of the source object with all lines indented by the
89
- given indent-string."""
90
- newsource = Source()
91
- newsource.raw_lines = self.raw_lines
92
- newsource.lines = [(indent + line) for line in self.lines]
93
- return newsource
94
-
95
- def getstatement(self, lineno: int) -> Source:
96
- """Return Source statement which contains the given linenumber
97
- (counted from 0)."""
98
- start, end = self.getstatementrange(lineno)
99
- return self[start:end]
100
-
101
- def getstatementrange(self, lineno: int) -> tuple[int, int]:
102
- """Return (start, end) tuple which spans the minimal statement region
103
- which containing the given lineno."""
104
- if not (0 <= lineno < len(self)):
105
- raise IndexError("lineno out of range")
106
- _ast, start, end = getstatementrange_ast(lineno, self)
107
- return start, end
108
-
109
- def deindent(self) -> Source:
110
- """Return a new Source object deindented."""
111
- newsource = Source()
112
- newsource.lines[:] = deindent(self.lines)
113
- newsource.raw_lines = self.raw_lines
114
- return newsource
115
-
116
- def __str__(self) -> str:
117
- return "\n".join(self.lines)
118
-
119
-
120
- #
121
- # helper functions
122
- #
123
-
124
-
125
- def findsource(obj) -> tuple[Source | None, int]:
126
- try:
127
- sourcelines, lineno = inspect.findsource(obj)
128
- except Exception:
129
- return None, -1
130
- source = Source()
131
- source.lines = [line.rstrip() for line in sourcelines]
132
- source.raw_lines = sourcelines
133
- return source, lineno
134
-
135
-
136
- def getrawcode(obj: object, trycall: bool = True) -> types.CodeType:
137
- """Return code object for given function."""
138
- try:
139
- return obj.__code__ # type: ignore[attr-defined,no-any-return]
140
- except AttributeError:
141
- pass
142
- if trycall:
143
- call = getattr(obj, "__call__", None)
144
- if call and not isinstance(obj, type):
145
- return getrawcode(call, trycall=False)
146
- raise TypeError(f"could not get code object for {obj!r}")
147
-
148
-
149
- def deindent(lines: Iterable[str]) -> list[str]:
150
- return textwrap.dedent("\n".join(lines)).splitlines()
151
-
152
-
153
- def get_statement_startend2(lineno: int, node: ast.AST) -> tuple[int, int | None]:
154
- # Flatten all statements and except handlers into one lineno-list.
155
- # AST's line numbers start indexing at 1.
156
- values: list[int] = []
157
- for x in ast.walk(node):
158
- if isinstance(x, ast.stmt | ast.ExceptHandler):
159
- # The lineno points to the class/def, so need to include the decorators.
160
- if isinstance(x, ast.ClassDef | ast.FunctionDef | ast.AsyncFunctionDef):
161
- for d in x.decorator_list:
162
- values.append(d.lineno - 1)
163
- values.append(x.lineno - 1)
164
- for name in ("finalbody", "orelse"):
165
- val: list[ast.stmt] | None = getattr(x, name, None)
166
- if val:
167
- # Treat the finally/orelse part as its own statement.
168
- values.append(val[0].lineno - 1 - 1)
169
- values.sort()
170
- insert_index = bisect_right(values, lineno)
171
- if insert_index == 0:
172
- return 0, None
173
- start = values[insert_index - 1]
174
- if insert_index >= len(values):
175
- end = None
176
- else:
177
- end = values[insert_index]
178
- return start, end
179
-
180
-
181
- def getstatementrange_ast(
182
- lineno: int,
183
- source: Source,
184
- assertion: bool = False,
185
- astnode: ast.AST | None = None,
186
- ) -> tuple[ast.AST, int, int]:
187
- if astnode is None:
188
- content = str(source)
189
- # See #4260:
190
- # Don't produce duplicate warnings when compiling source to find AST.
191
- with warnings.catch_warnings():
192
- warnings.simplefilter("ignore")
193
- astnode = ast.parse(content, "source", "exec")
194
-
195
- start, end = get_statement_startend2(lineno, astnode)
196
- # We need to correct the end:
197
- # - ast-parsing strips comments
198
- # - there might be empty lines
199
- # - we might have lesser indented code blocks at the end
200
- if end is None:
201
- end = len(source.lines)
202
-
203
- if end > start + 1:
204
- # Make sure we don't span differently indented code blocks
205
- # by using the BlockFinder helper used which inspect.getsource() uses itself.
206
- block_finder = inspect.BlockFinder()
207
- # If we start with an indented line, put blockfinder to "started" mode.
208
- block_finder.started = (
209
- bool(source.lines[start]) and source.lines[start][0].isspace()
210
- )
211
- it = ((x + "\n") for x in source.lines[start:end])
212
- try:
213
- for tok in tokenize.generate_tokens(lambda: next(it)):
214
- block_finder.tokeneater(*tok)
215
- except (inspect.EndOfBlock, IndentationError):
216
- end = block_finder.last + start
217
- except Exception:
218
- pass
219
-
220
- # The end might still point to a comment or empty line, correct it.
221
- end = min(end, len(source.lines))
222
- while end:
223
- line = source.lines[end - 1].lstrip()
224
- if line.startswith("#") or not line:
225
- end -= 1
226
- else:
227
- break
228
- return astnode, start, end
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.venv/lib/python3.12/site-packages/_pytest/_io/__init__.py DELETED
@@ -1,10 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from .terminalwriter import get_terminal_width
4
- from .terminalwriter import TerminalWriter
5
-
6
-
7
- __all__ = [
8
- "TerminalWriter",
9
- "get_terminal_width",
10
- ]
 
 
 
 
 
 
 
 
 
 
 
.venv/lib/python3.12/site-packages/_pytest/_io/pprint.py DELETED
@@ -1,673 +0,0 @@
1
- # mypy: allow-untyped-defs
2
- # This module was imported from the cpython standard library
3
- # (https://github.com/python/cpython/) at commit
4
- # c5140945c723ae6c4b7ee81ff720ac8ea4b52cfd (python3.12).
5
- #
6
- #
7
- # Original Author: Fred L. Drake, Jr.
8
- # fdrake@acm.org
9
- #
10
- # This is a simple little module I wrote to make life easier. I didn't
11
- # see anything quite like it in the library, though I may have overlooked
12
- # something. I wrote this when I was trying to read some heavily nested
13
- # tuples with fairly non-descriptive content. This is modeled very much
14
- # after Lisp/Scheme - style pretty-printing of lists. If you find it
15
- # useful, thank small children who sleep at night.
16
- from __future__ import annotations
17
-
18
- import collections as _collections
19
- from collections.abc import Callable
20
- from collections.abc import Iterator
21
- import dataclasses as _dataclasses
22
- from io import StringIO as _StringIO
23
- import re
24
- import types as _types
25
- from typing import Any
26
- from typing import IO
27
-
28
-
29
- class _safe_key:
30
- """Helper function for key functions when sorting unorderable objects.
31
-
32
- The wrapped-object will fallback to a Py2.x style comparison for
33
- unorderable types (sorting first comparing the type name and then by
34
- the obj ids). Does not work recursively, so dict.items() must have
35
- _safe_key applied to both the key and the value.
36
-
37
- """
38
-
39
- __slots__ = ["obj"]
40
-
41
- def __init__(self, obj):
42
- self.obj = obj
43
-
44
- def __lt__(self, other):
45
- try:
46
- return self.obj < other.obj
47
- except TypeError:
48
- return (str(type(self.obj)), id(self.obj)) < (
49
- str(type(other.obj)),
50
- id(other.obj),
51
- )
52
-
53
-
54
- def _safe_tuple(t):
55
- """Helper function for comparing 2-tuples"""
56
- return _safe_key(t[0]), _safe_key(t[1])
57
-
58
-
59
- class PrettyPrinter:
60
- def __init__(
61
- self,
62
- indent: int = 4,
63
- width: int = 80,
64
- depth: int | None = None,
65
- ) -> None:
66
- """Handle pretty printing operations onto a stream using a set of
67
- configured parameters.
68
-
69
- indent
70
- Number of spaces to indent for each level of nesting.
71
-
72
- width
73
- Attempted maximum number of columns in the output.
74
-
75
- depth
76
- The maximum depth to print out nested structures.
77
-
78
- """
79
- if indent < 0:
80
- raise ValueError("indent must be >= 0")
81
- if depth is not None and depth <= 0:
82
- raise ValueError("depth must be > 0")
83
- if not width:
84
- raise ValueError("width must be != 0")
85
- self._depth = depth
86
- self._indent_per_level = indent
87
- self._width = width
88
-
89
- def pformat(self, object: Any) -> str:
90
- sio = _StringIO()
91
- self._format(object, sio, 0, 0, set(), 0)
92
- return sio.getvalue()
93
-
94
- def _format(
95
- self,
96
- object: Any,
97
- stream: IO[str],
98
- indent: int,
99
- allowance: int,
100
- context: set[int],
101
- level: int,
102
- ) -> None:
103
- objid = id(object)
104
- if objid in context:
105
- stream.write(_recursion(object))
106
- return
107
-
108
- p = self._dispatch.get(type(object).__repr__, None)
109
- if p is not None:
110
- context.add(objid)
111
- p(self, object, stream, indent, allowance, context, level + 1)
112
- context.remove(objid)
113
- elif (
114
- _dataclasses.is_dataclass(object)
115
- and not isinstance(object, type)
116
- and object.__dataclass_params__.repr # type:ignore[attr-defined]
117
- and
118
- # Check dataclass has generated repr method.
119
- hasattr(object.__repr__, "__wrapped__")
120
- and "__create_fn__" in object.__repr__.__wrapped__.__qualname__
121
- ):
122
- context.add(objid)
123
- self._pprint_dataclass(
124
- object, stream, indent, allowance, context, level + 1
125
- )
126
- context.remove(objid)
127
- else:
128
- stream.write(self._repr(object, context, level))
129
-
130
- def _pprint_dataclass(
131
- self,
132
- object: Any,
133
- stream: IO[str],
134
- indent: int,
135
- allowance: int,
136
- context: set[int],
137
- level: int,
138
- ) -> None:
139
- cls_name = object.__class__.__name__
140
- items = [
141
- (f.name, getattr(object, f.name))
142
- for f in _dataclasses.fields(object)
143
- if f.repr
144
- ]
145
- stream.write(cls_name + "(")
146
- self._format_namespace_items(items, stream, indent, allowance, context, level)
147
- stream.write(")")
148
-
149
- _dispatch: dict[
150
- Callable[..., str],
151
- Callable[[PrettyPrinter, Any, IO[str], int, int, set[int], int], None],
152
- ] = {}
153
-
154
- def _pprint_dict(
155
- self,
156
- object: Any,
157
- stream: IO[str],
158
- indent: int,
159
- allowance: int,
160
- context: set[int],
161
- level: int,
162
- ) -> None:
163
- write = stream.write
164
- write("{")
165
- items = object.items()
166
- self._format_dict_items(items, stream, indent, allowance, context, level)
167
- write("}")
168
-
169
- _dispatch[dict.__repr__] = _pprint_dict
170
-
171
- def _pprint_ordered_dict(
172
- self,
173
- object: Any,
174
- stream: IO[str],
175
- indent: int,
176
- allowance: int,
177
- context: set[int],
178
- level: int,
179
- ) -> None:
180
- if not len(object):
181
- stream.write(repr(object))
182
- return
183
- cls = object.__class__
184
- stream.write(cls.__name__ + "(")
185
- self._pprint_dict(object, stream, indent, allowance, context, level)
186
- stream.write(")")
187
-
188
- _dispatch[_collections.OrderedDict.__repr__] = _pprint_ordered_dict
189
-
190
- def _pprint_list(
191
- self,
192
- object: Any,
193
- stream: IO[str],
194
- indent: int,
195
- allowance: int,
196
- context: set[int],
197
- level: int,
198
- ) -> None:
199
- stream.write("[")
200
- self._format_items(object, stream, indent, allowance, context, level)
201
- stream.write("]")
202
-
203
- _dispatch[list.__repr__] = _pprint_list
204
-
205
- def _pprint_tuple(
206
- self,
207
- object: Any,
208
- stream: IO[str],
209
- indent: int,
210
- allowance: int,
211
- context: set[int],
212
- level: int,
213
- ) -> None:
214
- stream.write("(")
215
- self._format_items(object, stream, indent, allowance, context, level)
216
- stream.write(")")
217
-
218
- _dispatch[tuple.__repr__] = _pprint_tuple
219
-
220
- def _pprint_set(
221
- self,
222
- object: Any,
223
- stream: IO[str],
224
- indent: int,
225
- allowance: int,
226
- context: set[int],
227
- level: int,
228
- ) -> None:
229
- if not len(object):
230
- stream.write(repr(object))
231
- return
232
- typ = object.__class__
233
- if typ is set:
234
- stream.write("{")
235
- endchar = "}"
236
- else:
237
- stream.write(typ.__name__ + "({")
238
- endchar = "})"
239
- object = sorted(object, key=_safe_key)
240
- self._format_items(object, stream, indent, allowance, context, level)
241
- stream.write(endchar)
242
-
243
- _dispatch[set.__repr__] = _pprint_set
244
- _dispatch[frozenset.__repr__] = _pprint_set
245
-
246
- def _pprint_str(
247
- self,
248
- object: Any,
249
- stream: IO[str],
250
- indent: int,
251
- allowance: int,
252
- context: set[int],
253
- level: int,
254
- ) -> None:
255
- write = stream.write
256
- if not len(object):
257
- write(repr(object))
258
- return
259
- chunks = []
260
- lines = object.splitlines(True)
261
- if level == 1:
262
- indent += 1
263
- allowance += 1
264
- max_width1 = max_width = self._width - indent
265
- for i, line in enumerate(lines):
266
- rep = repr(line)
267
- if i == len(lines) - 1:
268
- max_width1 -= allowance
269
- if len(rep) <= max_width1:
270
- chunks.append(rep)
271
- else:
272
- # A list of alternating (non-space, space) strings
273
- parts = re.findall(r"\S*\s*", line)
274
- assert parts
275
- assert not parts[-1]
276
- parts.pop() # drop empty last part
277
- max_width2 = max_width
278
- current = ""
279
- for j, part in enumerate(parts):
280
- candidate = current + part
281
- if j == len(parts) - 1 and i == len(lines) - 1:
282
- max_width2 -= allowance
283
- if len(repr(candidate)) > max_width2:
284
- if current:
285
- chunks.append(repr(current))
286
- current = part
287
- else:
288
- current = candidate
289
- if current:
290
- chunks.append(repr(current))
291
- if len(chunks) == 1:
292
- write(rep)
293
- return
294
- if level == 1:
295
- write("(")
296
- for i, rep in enumerate(chunks):
297
- if i > 0:
298
- write("\n" + " " * indent)
299
- write(rep)
300
- if level == 1:
301
- write(")")
302
-
303
- _dispatch[str.__repr__] = _pprint_str
304
-
305
- def _pprint_bytes(
306
- self,
307
- object: Any,
308
- stream: IO[str],
309
- indent: int,
310
- allowance: int,
311
- context: set[int],
312
- level: int,
313
- ) -> None:
314
- write = stream.write
315
- if len(object) <= 4:
316
- write(repr(object))
317
- return
318
- parens = level == 1
319
- if parens:
320
- indent += 1
321
- allowance += 1
322
- write("(")
323
- delim = ""
324
- for rep in _wrap_bytes_repr(object, self._width - indent, allowance):
325
- write(delim)
326
- write(rep)
327
- if not delim:
328
- delim = "\n" + " " * indent
329
- if parens:
330
- write(")")
331
-
332
- _dispatch[bytes.__repr__] = _pprint_bytes
333
-
334
- def _pprint_bytearray(
335
- self,
336
- object: Any,
337
- stream: IO[str],
338
- indent: int,
339
- allowance: int,
340
- context: set[int],
341
- level: int,
342
- ) -> None:
343
- write = stream.write
344
- write("bytearray(")
345
- self._pprint_bytes(
346
- bytes(object), stream, indent + 10, allowance + 1, context, level + 1
347
- )
348
- write(")")
349
-
350
- _dispatch[bytearray.__repr__] = _pprint_bytearray
351
-
352
- def _pprint_mappingproxy(
353
- self,
354
- object: Any,
355
- stream: IO[str],
356
- indent: int,
357
- allowance: int,
358
- context: set[int],
359
- level: int,
360
- ) -> None:
361
- stream.write("mappingproxy(")
362
- self._format(object.copy(), stream, indent, allowance, context, level)
363
- stream.write(")")
364
-
365
- _dispatch[_types.MappingProxyType.__repr__] = _pprint_mappingproxy
366
-
367
- def _pprint_simplenamespace(
368
- self,
369
- object: Any,
370
- stream: IO[str],
371
- indent: int,
372
- allowance: int,
373
- context: set[int],
374
- level: int,
375
- ) -> None:
376
- if type(object) is _types.SimpleNamespace:
377
- # The SimpleNamespace repr is "namespace" instead of the class
378
- # name, so we do the same here. For subclasses; use the class name.
379
- cls_name = "namespace"
380
- else:
381
- cls_name = object.__class__.__name__
382
- items = object.__dict__.items()
383
- stream.write(cls_name + "(")
384
- self._format_namespace_items(items, stream, indent, allowance, context, level)
385
- stream.write(")")
386
-
387
- _dispatch[_types.SimpleNamespace.__repr__] = _pprint_simplenamespace
388
-
389
- def _format_dict_items(
390
- self,
391
- items: list[tuple[Any, Any]],
392
- stream: IO[str],
393
- indent: int,
394
- allowance: int,
395
- context: set[int],
396
- level: int,
397
- ) -> None:
398
- if not items:
399
- return
400
-
401
- write = stream.write
402
- item_indent = indent + self._indent_per_level
403
- delimnl = "\n" + " " * item_indent
404
- for key, ent in items:
405
- write(delimnl)
406
- write(self._repr(key, context, level))
407
- write(": ")
408
- self._format(ent, stream, item_indent, 1, context, level)
409
- write(",")
410
-
411
- write("\n" + " " * indent)
412
-
413
- def _format_namespace_items(
414
- self,
415
- items: list[tuple[Any, Any]],
416
- stream: IO[str],
417
- indent: int,
418
- allowance: int,
419
- context: set[int],
420
- level: int,
421
- ) -> None:
422
- if not items:
423
- return
424
-
425
- write = stream.write
426
- item_indent = indent + self._indent_per_level
427
- delimnl = "\n" + " " * item_indent
428
- for key, ent in items:
429
- write(delimnl)
430
- write(key)
431
- write("=")
432
- if id(ent) in context:
433
- # Special-case representation of recursion to match standard
434
- # recursive dataclass repr.
435
- write("...")
436
- else:
437
- self._format(
438
- ent,
439
- stream,
440
- item_indent + len(key) + 1,
441
- 1,
442
- context,
443
- level,
444
- )
445
-
446
- write(",")
447
-
448
- write("\n" + " " * indent)
449
-
450
- def _format_items(
451
- self,
452
- items: list[Any],
453
- stream: IO[str],
454
- indent: int,
455
- allowance: int,
456
- context: set[int],
457
- level: int,
458
- ) -> None:
459
- if not items:
460
- return
461
-
462
- write = stream.write
463
- item_indent = indent + self._indent_per_level
464
- delimnl = "\n" + " " * item_indent
465
-
466
- for item in items:
467
- write(delimnl)
468
- self._format(item, stream, item_indent, 1, context, level)
469
- write(",")
470
-
471
- write("\n" + " " * indent)
472
-
473
- def _repr(self, object: Any, context: set[int], level: int) -> str:
474
- return self._safe_repr(object, context.copy(), self._depth, level)
475
-
476
- def _pprint_default_dict(
477
- self,
478
- object: Any,
479
- stream: IO[str],
480
- indent: int,
481
- allowance: int,
482
- context: set[int],
483
- level: int,
484
- ) -> None:
485
- rdf = self._repr(object.default_factory, context, level)
486
- stream.write(f"{object.__class__.__name__}({rdf}, ")
487
- self._pprint_dict(object, stream, indent, allowance, context, level)
488
- stream.write(")")
489
-
490
- _dispatch[_collections.defaultdict.__repr__] = _pprint_default_dict
491
-
492
- def _pprint_counter(
493
- self,
494
- object: Any,
495
- stream: IO[str],
496
- indent: int,
497
- allowance: int,
498
- context: set[int],
499
- level: int,
500
- ) -> None:
501
- stream.write(object.__class__.__name__ + "(")
502
-
503
- if object:
504
- stream.write("{")
505
- items = object.most_common()
506
- self._format_dict_items(items, stream, indent, allowance, context, level)
507
- stream.write("}")
508
-
509
- stream.write(")")
510
-
511
- _dispatch[_collections.Counter.__repr__] = _pprint_counter
512
-
513
- def _pprint_chain_map(
514
- self,
515
- object: Any,
516
- stream: IO[str],
517
- indent: int,
518
- allowance: int,
519
- context: set[int],
520
- level: int,
521
- ) -> None:
522
- if not len(object.maps) or (len(object.maps) == 1 and not len(object.maps[0])):
523
- stream.write(repr(object))
524
- return
525
-
526
- stream.write(object.__class__.__name__ + "(")
527
- self._format_items(object.maps, stream, indent, allowance, context, level)
528
- stream.write(")")
529
-
530
- _dispatch[_collections.ChainMap.__repr__] = _pprint_chain_map
531
-
532
- def _pprint_deque(
533
- self,
534
- object: Any,
535
- stream: IO[str],
536
- indent: int,
537
- allowance: int,
538
- context: set[int],
539
- level: int,
540
- ) -> None:
541
- stream.write(object.__class__.__name__ + "(")
542
- if object.maxlen is not None:
543
- stream.write(f"maxlen={object.maxlen}, ")
544
- stream.write("[")
545
-
546
- self._format_items(object, stream, indent, allowance + 1, context, level)
547
- stream.write("])")
548
-
549
- _dispatch[_collections.deque.__repr__] = _pprint_deque
550
-
551
- def _pprint_user_dict(
552
- self,
553
- object: Any,
554
- stream: IO[str],
555
- indent: int,
556
- allowance: int,
557
- context: set[int],
558
- level: int,
559
- ) -> None:
560
- self._format(object.data, stream, indent, allowance, context, level - 1)
561
-
562
- _dispatch[_collections.UserDict.__repr__] = _pprint_user_dict
563
-
564
- def _pprint_user_list(
565
- self,
566
- object: Any,
567
- stream: IO[str],
568
- indent: int,
569
- allowance: int,
570
- context: set[int],
571
- level: int,
572
- ) -> None:
573
- self._format(object.data, stream, indent, allowance, context, level - 1)
574
-
575
- _dispatch[_collections.UserList.__repr__] = _pprint_user_list
576
-
577
- def _pprint_user_string(
578
- self,
579
- object: Any,
580
- stream: IO[str],
581
- indent: int,
582
- allowance: int,
583
- context: set[int],
584
- level: int,
585
- ) -> None:
586
- self._format(object.data, stream, indent, allowance, context, level - 1)
587
-
588
- _dispatch[_collections.UserString.__repr__] = _pprint_user_string
589
-
590
- def _safe_repr(
591
- self, object: Any, context: set[int], maxlevels: int | None, level: int
592
- ) -> str:
593
- typ = type(object)
594
- if typ in _builtin_scalars:
595
- return repr(object)
596
-
597
- r = getattr(typ, "__repr__", None)
598
-
599
- if issubclass(typ, dict) and r is dict.__repr__:
600
- if not object:
601
- return "{}"
602
- objid = id(object)
603
- if maxlevels and level >= maxlevels:
604
- return "{...}"
605
- if objid in context:
606
- return _recursion(object)
607
- context.add(objid)
608
- components: list[str] = []
609
- append = components.append
610
- level += 1
611
- for k, v in object.items():
612
- krepr = self._safe_repr(k, context, maxlevels, level)
613
- vrepr = self._safe_repr(v, context, maxlevels, level)
614
- append(f"{krepr}: {vrepr}")
615
- context.remove(objid)
616
- return "{{{}}}".format(", ".join(components))
617
-
618
- if (issubclass(typ, list) and r is list.__repr__) or (
619
- issubclass(typ, tuple) and r is tuple.__repr__
620
- ):
621
- if issubclass(typ, list):
622
- if not object:
623
- return "[]"
624
- format = "[%s]"
625
- elif len(object) == 1:
626
- format = "(%s,)"
627
- else:
628
- if not object:
629
- return "()"
630
- format = "(%s)"
631
- objid = id(object)
632
- if maxlevels and level >= maxlevels:
633
- return format % "..."
634
- if objid in context:
635
- return _recursion(object)
636
- context.add(objid)
637
- components = []
638
- append = components.append
639
- level += 1
640
- for o in object:
641
- orepr = self._safe_repr(o, context, maxlevels, level)
642
- append(orepr)
643
- context.remove(objid)
644
- return format % ", ".join(components)
645
-
646
- return repr(object)
647
-
648
-
649
- _builtin_scalars = frozenset(
650
- {str, bytes, bytearray, float, complex, bool, type(None), int}
651
- )
652
-
653
-
654
- def _recursion(object: Any) -> str:
655
- return f"<Recursion on {type(object).__name__} with id={id(object)}>"
656
-
657
-
658
- def _wrap_bytes_repr(object: Any, width: int, allowance: int) -> Iterator[str]:
659
- current = b""
660
- last = len(object) // 4 * 4
661
- for i in range(0, len(object), 4):
662
- part = object[i : i + 4]
663
- candidate = current + part
664
- if i == last:
665
- width -= allowance
666
- if len(repr(candidate)) > width:
667
- if current:
668
- yield repr(current)
669
- current = part
670
- else:
671
- current = candidate
672
- if current:
673
- yield repr(current)