hunterMakesPy 0.3.3__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,12 @@
1
1
  # pyright: standard
2
+ """Tests for filesystem toolkit utilities.
3
+
4
+ (AI generated docstring)
5
+
6
+ This module validates the behavior of file and directory operations,
7
+ including safe directory creation, file writing, and dynamic importing.
8
+
9
+ """
2
10
  from hunterMakesPy import (
3
11
  importLogicalPath2Identifier, importPathFilename2Identifier, makeDirsSafely, writePython, writeStringToHere)
4
12
  from hunterMakesPy.tests.conftest import standardizedEqualTo
@@ -18,14 +26,22 @@ import sys
18
26
  ('sys', 'version', None, type(sys.version)),
19
27
  ]
20
28
  )
21
- def testImportLogicalPath2IdentifierWithAbsolutePaths(
22
- logicalPathModuleTarget: str,
23
- identifierTarget: str,
24
- packageIdentifierIfRelativeTarget: str | None,
25
- expectedType: type
26
- ) -> None:
27
- """Test importing identifiers from modules using absolute logical paths."""
28
- identifierImported = importLogicalPath2Identifier(logicalPathModuleTarget, identifierTarget, packageIdentifierIfRelativeTarget)
29
+ def testImportLogicalPath2IdentifierWithAbsolutePaths(logicalPathModuleTarget: str, identifierTarget: str, packageIdentifierIfRelativeTarget: str | None, expectedType: type) -> None:
30
+ """Test importing identifiers from modules using absolute logical paths.
31
+
32
+ Parameters
33
+ ----------
34
+ logicalPathModuleTarget : str
35
+ The logical path of the module (e.g., 'os.path').
36
+ identifierTarget : str
37
+ The identifier (function/class) to import.
38
+ packageIdentifierIfRelativeTarget : str | None
39
+ Expected to be None for absolute paths.
40
+ expectedType : type
41
+ The expected type of the imported object.
42
+
43
+ """
44
+ identifierImported: object = importLogicalPath2Identifier(logicalPathModuleTarget, identifierTarget, packageIdentifierIfRelativeTarget)
29
45
 
30
46
  assert isinstance(identifierImported, expectedType), (
31
47
  f"\nTesting: `importLogicalPath2Identifier({logicalPathModuleTarget}, {identifierTarget}, {packageIdentifierIfRelativeTarget})`\n"
@@ -33,7 +49,6 @@ def testImportLogicalPath2IdentifierWithAbsolutePaths(
33
49
  f"Got type: {type(identifierImported)}"
34
50
  )
35
51
 
36
-
37
52
  @pytest.mark.parametrize(
38
53
  "pythonSourceTarget, identifierTarget, moduleIdentifierTarget, expectedValueWhenCalled",
39
54
  [
@@ -43,23 +58,34 @@ def testImportLogicalPath2IdentifierWithAbsolutePaths(
43
58
  ("def fibonacciSequence():\n return 21\n", "fibonacciSequence", "moduleEast", 21),
44
59
  ]
45
60
  )
46
- def testImportPathFilename2IdentifierWithCallables(
47
- pathTmpTesting: pathlib.Path,
48
- pythonSourceTarget: str,
49
- identifierTarget: str,
50
- moduleIdentifierTarget: str | None,
51
- expectedValueWhenCalled: object
52
- ) -> None:
53
- """Test importing callable identifiers from Python files."""
54
- pathFilenameModule = pathTmpTesting / f"moduleTest{hash(pythonSourceTarget) % 89}.py" # Use prime number 89
61
+ def testImportPathFilename2IdentifierWithCallables(pathTmpTesting: pathlib.Path, pythonSourceTarget: str, identifierTarget: str, moduleIdentifierTarget: str | None, expectedValueWhenCalled: object) -> None:
62
+ """Test importing callable identifiers from Python files.
63
+
64
+ Parameters
65
+ ----------
66
+ pathTmpTesting : pathlib.Path
67
+ Temporary directory fixture.
68
+ pythonSourceTarget : str
69
+ Source code to write to the temporary file.
70
+ identifierTarget : str
71
+ The callable identifier to import.
72
+ moduleIdentifierTarget : str | None
73
+ Optional module name hint.
74
+ expectedValueWhenCalled : object
75
+ The expected return value when calling the imported object.
76
+
77
+ """
78
+ pathFilenameModule: pathlib.Path = pathTmpTesting / f"moduleTest{hash(pythonSourceTarget) % 89}.py" # Use prime number 89
55
79
  pathFilenameModule.write_text(pythonSourceTarget)
56
80
 
81
+ def callImportedIdentifier() -> object:
82
+ return importPathFilename2Identifier(pathFilenameModule, identifierTarget, moduleIdentifierTarget)()
83
+
57
84
  standardizedEqualTo(
58
85
  expectedValueWhenCalled,
59
- lambda: importPathFilename2Identifier(pathFilenameModule, identifierTarget, moduleIdentifierTarget)(),
86
+ callImportedIdentifier,
60
87
  )
61
88
 
62
-
63
89
  @pytest.mark.parametrize(
64
90
  "pythonSourceTarget, identifierTarget, moduleIdentifierTarget, expectedValue",
65
91
  [
@@ -69,15 +95,24 @@ def testImportPathFilename2IdentifierWithCallables(
69
95
  ("sequenceValue = 55\n", "sequenceValue", "moduleSouthWest", 55),
70
96
  ]
71
97
  )
72
- def testImportPathFilename2IdentifierWithVariables(
73
- pathTmpTesting: pathlib.Path,
74
- pythonSourceTarget: str,
75
- identifierTarget: str,
76
- moduleIdentifierTarget: str | None,
77
- expectedValue: object
78
- ) -> None:
79
- """Test importing variable identifiers from Python files."""
80
- pathFilenameModule = pathTmpTesting / f"moduleTest{hash(pythonSourceTarget) % 97}.py" # Use prime number 97
98
+ def testImportPathFilename2IdentifierWithVariables(pathTmpTesting: pathlib.Path, pythonSourceTarget: str, identifierTarget: str, moduleIdentifierTarget: str | None, expectedValue: object) -> None:
99
+ """Test importing variable identifiers from Python files.
100
+
101
+ Parameters
102
+ ----------
103
+ pathTmpTesting : pathlib.Path
104
+ Temporary directory fixture.
105
+ pythonSourceTarget : str
106
+ Source code to write to the temporary file.
107
+ identifierTarget : str
108
+ The variable identifier to import.
109
+ moduleIdentifierTarget : str | None
110
+ Optional module name hint.
111
+ expectedValue : object
112
+ The expected value of the imported variable.
113
+
114
+ """
115
+ pathFilenameModule: pathlib.Path = pathTmpTesting / f"moduleTest{hash(pythonSourceTarget) % 97}.py" # Use prime number 97
81
116
  pathFilenameModule.write_text(pythonSourceTarget)
82
117
 
83
118
  standardizedEqualTo(
@@ -88,7 +123,6 @@ def testImportPathFilename2IdentifierWithVariables(
88
123
  moduleIdentifierTarget
89
124
  )
90
125
 
91
-
92
126
  @pytest.mark.parametrize(
93
127
  "listDirectoryComponents, filenameTarget",
94
128
  [
@@ -98,17 +132,24 @@ def testImportPathFilename2IdentifierWithVariables(
98
132
  (['cardinal', 'directions', 'multiple'], 'prime23.txt'),
99
133
  ]
100
134
  )
101
- def testMakeDirsSafelyCreatesNestedDirectories(
102
- pathTmpTesting: pathlib.Path,
103
- listDirectoryComponents: list[str],
104
- filenameTarget: str
105
- ) -> None:
106
- """Test that makeDirsSafely creates nested parent directories."""
107
- pathDirectoryNested = pathTmpTesting
135
+ def testMakeDirsSafelyCreatesNestedDirectories(pathTmpTesting: pathlib.Path, listDirectoryComponents: list[str], filenameTarget: str) -> None:
136
+ """Test that makeDirsSafely creates nested parent directories.
137
+
138
+ Parameters
139
+ ----------
140
+ pathTmpTesting : pathlib.Path
141
+ Temporary directory fixture.
142
+ listDirectoryComponents : list[str]
143
+ List of nested directory names.
144
+ filenameTarget : str
145
+ Name of the target file inside the nested directories.
146
+
147
+ """
148
+ pathDirectoryNested: pathlib.Path = pathTmpTesting
108
149
  for directoryComponent in listDirectoryComponents:
109
150
  pathDirectoryNested = pathDirectoryNested / directoryComponent
110
151
 
111
- pathFilenameTarget = pathDirectoryNested / filenameTarget
152
+ pathFilenameTarget: pathlib.Path = pathDirectoryNested / filenameTarget
112
153
  makeDirsSafely(pathFilenameTarget)
113
154
 
114
155
  assert pathDirectoryNested.exists() and pathDirectoryNested.is_dir(), (
@@ -117,7 +158,6 @@ def testMakeDirsSafelyCreatesNestedDirectories(
117
158
  f"Got: exists={pathDirectoryNested.exists()}, is_dir={pathDirectoryNested.is_dir() if pathDirectoryNested.exists() else False}"
118
159
  )
119
160
 
120
-
121
161
  @pytest.mark.parametrize(
122
162
  "streamTypeTarget",
123
163
  [
@@ -126,14 +166,20 @@ def testMakeDirsSafelyCreatesNestedDirectories(
126
166
  ]
127
167
  )
128
168
  def testMakeDirsSafelyWithIOStreamDoesNotRaise(streamTypeTarget: io.IOBase) -> None:
129
- """Test that makeDirsSafely handles IO streams without raising exceptions."""
169
+ """Test that makeDirsSafely handles IO streams without raising exceptions.
170
+
171
+ Parameters
172
+ ----------
173
+ streamTypeTarget : io.IOBase
174
+ The IO stream object to test.
175
+
176
+ """
130
177
  # This test verifies that no exception is raised
131
178
  makeDirsSafely(streamTypeTarget)
132
179
 
133
180
  # If we reach this point, no exception was raised
134
181
  assert True
135
182
 
136
-
137
183
  @pytest.mark.parametrize(
138
184
  "listDirectoryComponents, filenameTarget, contentTarget",
139
185
  [
@@ -143,18 +189,26 @@ def testMakeDirsSafelyWithIOStreamDoesNotRaise(streamTypeTarget: io.IOBase) -> N
143
189
  (['west', 'sequence'], 'test23.txt', 'sequence value 23'),
144
190
  ]
145
191
  )
146
- def testWriteStringToHereCreatesFileAndDirectories(
147
- pathTmpTesting: pathlib.Path,
148
- listDirectoryComponents: list[str],
149
- filenameTarget: str,
150
- contentTarget: str
151
- ) -> None:
152
- """Test that writeStringToHere creates directories and writes content to files."""
153
- pathDirectoryNested = pathTmpTesting
192
+ def testWriteStringToHereCreatesFileAndDirectories(pathTmpTesting: pathlib.Path, listDirectoryComponents: list[str], filenameTarget: str, contentTarget: str) -> None:
193
+ """Test that writeStringToHere creates directories and writes content to files.
194
+
195
+ Parameters
196
+ ----------
197
+ pathTmpTesting : pathlib.Path
198
+ Temporary directory fixture.
199
+ listDirectoryComponents : list[str]
200
+ Nested directory names.
201
+ filenameTarget : str
202
+ Target filename.
203
+ contentTarget : str
204
+ Content to write to the file.
205
+
206
+ """
207
+ pathDirectoryNested: pathlib.Path = pathTmpTesting
154
208
  for directoryComponent in listDirectoryComponents:
155
209
  pathDirectoryNested = pathDirectoryNested / directoryComponent
156
210
 
157
- pathFilenameTarget = pathDirectoryNested / filenameTarget
211
+ pathFilenameTarget: pathlib.Path = pathDirectoryNested / filenameTarget
158
212
  writeStringToHere(contentTarget, pathFilenameTarget)
159
213
 
160
214
  assert pathFilenameTarget.exists(), (
@@ -163,14 +217,13 @@ def testWriteStringToHereCreatesFileAndDirectories(
163
217
  f"Got: exists={pathFilenameTarget.exists()}"
164
218
  )
165
219
 
166
- contentActual = pathFilenameTarget.read_text(encoding="utf-8")
220
+ contentActual: str = pathFilenameTarget.read_text(encoding="utf-8")
167
221
  assert contentActual == contentTarget, (
168
222
  f"\nTesting: `writeStringToHere({contentTarget}, {pathFilenameTarget})`\n"
169
223
  f"Expected content: {contentTarget}\n"
170
224
  f"Got content: {contentActual}"
171
225
  )
172
226
 
173
-
174
227
  @pytest.mark.parametrize(
175
228
  "contentTarget",
176
229
  [
@@ -181,18 +234,24 @@ def testWriteStringToHereCreatesFileAndDirectories(
181
234
  ]
182
235
  )
183
236
  def testWriteStringToHereWithIOStream(contentTarget: str) -> None:
184
- """Test that writeStringToHere writes content to IO streams."""
185
- streamMemory = io.StringIO()
237
+ """Test that writeStringToHere writes content to IO streams.
238
+
239
+ Parameters
240
+ ----------
241
+ contentTarget : str
242
+ Content to write to the stream.
243
+
244
+ """
245
+ streamMemory: io.StringIO = io.StringIO()
186
246
  writeStringToHere(contentTarget, streamMemory)
187
247
 
188
- contentActual = streamMemory.getvalue()
248
+ contentActual: str = streamMemory.getvalue()
189
249
  assert contentActual == contentTarget, (
190
250
  f"\nTesting: `writeStringToHere({contentTarget}, StringIO)`\n"
191
251
  f"Expected content: {contentTarget}\n"
192
252
  f"Got content: {contentActual}"
193
253
  )
194
254
 
195
-
196
255
  @pytest.mark.parametrize(
197
256
  "logicalPathModuleTarget, identifierTarget, expectedExceptionType",
198
257
  [
@@ -206,14 +265,19 @@ def testImportLogicalPath2IdentifierWithInvalidInputs(
206
265
  identifierTarget: str,
207
266
  expectedExceptionType: type[Exception]
208
267
  ) -> None:
209
- """Test that importLogicalPath2Identifier raises appropriate exceptions for invalid inputs."""
210
- standardizedEqualTo(
211
- expectedExceptionType,
212
- importLogicalPath2Identifier,
213
- logicalPathModuleTarget,
214
- identifierTarget
215
- )
268
+ """Test that importLogicalPath2Identifier raises appropriate exceptions for invalid inputs.
269
+
270
+ Parameters
271
+ ----------
272
+ logicalPathModuleTarget : str
273
+ Invalid module path.
274
+ identifierTarget : str
275
+ Identifier to import.
276
+ expectedExceptionType : type[Exception]
277
+ The expected exception type.
216
278
 
279
+ """
280
+ standardizedEqualTo( expectedExceptionType, importLogicalPath2Identifier, logicalPathModuleTarget, identifierTarget )
217
281
 
218
282
  @pytest.mark.parametrize(
219
283
  "pathFilenameTarget, identifierTarget, expectedExceptionType",
@@ -221,22 +285,24 @@ def testImportLogicalPath2IdentifierWithInvalidInputs(
221
285
  ('nonexistent.py', 'anyIdentifier', FileNotFoundError),
222
286
  ]
223
287
  )
224
- def testImportPathFilename2IdentifierWithInvalidInputs(
225
- pathTmpTesting: pathlib.Path,
226
- pathFilenameTarget: str,
227
- identifierTarget: str,
228
- expectedExceptionType: type[Exception]
229
- ) -> None:
230
- """Test that importPathFilename2Identifier raises appropriate exceptions for invalid inputs."""
231
- pathFilenameNonexistent = pathTmpTesting / pathFilenameTarget
288
+ def testImportPathFilename2IdentifierWithInvalidInputs(pathTmpTesting: pathlib.Path, pathFilenameTarget: str, identifierTarget: str, expectedExceptionType: type[Exception]) -> None:
289
+ """Test that importPathFilename2Identifier raises appropriate exceptions for invalid inputs.
232
290
 
233
- standardizedEqualTo(
234
- expectedExceptionType,
235
- importPathFilename2Identifier,
236
- pathFilenameNonexistent,
237
- identifierTarget
238
- )
291
+ Parameters
292
+ ----------
293
+ pathTmpTesting : pathlib.Path
294
+ Temporary directory fixture.
295
+ pathFilenameTarget : str
296
+ Invalid or nonexistent filename.
297
+ identifierTarget : str
298
+ Identifier to import.
299
+ expectedExceptionType : type[Exception]
300
+ The expected exception type.
239
301
 
302
+ """
303
+ pathFilenameNonexistent: pathlib.Path = pathTmpTesting / pathFilenameTarget
304
+
305
+ standardizedEqualTo( expectedExceptionType, importPathFilename2Identifier, pathFilenameNonexistent, identifierTarget )
240
306
 
241
307
  @pytest.mark.parametrize(
242
308
  "pythonSourceTarget, identifierTarget, expectedExceptionType",
@@ -251,17 +317,24 @@ def testImportPathFilename2IdentifierWithValidFileInvalidIdentifier(
251
317
  identifierTarget: str,
252
318
  expectedExceptionType: type[Exception]
253
319
  ) -> None:
254
- """Test that importPathFilename2Identifier raises AttributeError for nonexistent identifiers in valid files."""
255
- pathFilenameModule = pathTmpTesting / f"moduleTest{hash(pythonSourceTarget) % 101}.py" # Use prime number 101
320
+ """Test that importPathFilename2Identifier raises AttributeError for nonexistent identifiers.
321
+
322
+ Parameters
323
+ ----------
324
+ pathTmpTesting : pathlib.Path
325
+ Temporary directory fixture.
326
+ pythonSourceTarget : str
327
+ Valid python source code.
328
+ identifierTarget : str
329
+ Identifier that does not exist in the source.
330
+ expectedExceptionType : type[Exception]
331
+ Expected exception (usually AttributeError).
332
+
333
+ """
334
+ pathFilenameModule: pathlib.Path = pathTmpTesting / f"moduleTest{hash(pythonSourceTarget) % 101}.py" # Use prime number 101
256
335
  pathFilenameModule.write_text(pythonSourceTarget)
257
336
 
258
- standardizedEqualTo(
259
- expectedExceptionType,
260
- importPathFilename2Identifier,
261
- pathFilenameModule,
262
- identifierTarget
263
- )
264
-
337
+ standardizedEqualTo( expectedExceptionType, importPathFilename2Identifier, pathFilenameModule, identifierTarget )
265
338
 
266
339
  @pytest.mark.parametrize(
267
340
  "pythonSourceTarget, expectedFormattedContent",
@@ -284,13 +357,20 @@ def testImportPathFilename2IdentifierWithValidFileInvalidIdentifier(
284
357
  ),
285
358
  ]
286
359
  )
287
- def testWritePythonFormatsAndWritesToFile(
288
- pathTmpTesting: pathlib.Path,
289
- pythonSourceTarget: str,
290
- expectedFormattedContent: str
291
- ) -> None:
292
- """Test that writePython formats Python source code and writes it to files."""
293
- pathFilenameTarget = pathTmpTesting / "formattedModule.py"
360
+ def testWritePythonFormatsAndWritesToFile(pathTmpTesting: pathlib.Path, pythonSourceTarget: str, expectedFormattedContent: str) -> None:
361
+ """Test that writePython formats Python source code and writes it to files.
362
+
363
+ Parameters
364
+ ----------
365
+ pathTmpTesting : pathlib.Path
366
+ Temporary directory fixture.
367
+ pythonSourceTarget : str
368
+ Unformatted python source.
369
+ expectedFormattedContent : str
370
+ Expected formatted content.
371
+
372
+ """
373
+ pathFilenameTarget: pathlib.Path = pathTmpTesting / "formattedModule.py"
294
374
  writePython(pythonSourceTarget, pathFilenameTarget)
295
375
 
296
376
  assert pathFilenameTarget.exists(), (
@@ -299,14 +379,13 @@ def testWritePythonFormatsAndWritesToFile(
299
379
  f"Got: exists={pathFilenameTarget.exists()}"
300
380
  )
301
381
 
302
- contentActual = pathFilenameTarget.read_text(encoding="utf-8")
382
+ contentActual: str = pathFilenameTarget.read_text(encoding="utf-8")
303
383
  assert contentActual == expectedFormattedContent, (
304
384
  f"\nTesting: `writePython(...)`\n"
305
385
  f"Expected content:\n{repr(expectedFormattedContent)}\n"
306
386
  f"Got content:\n{repr(contentActual)}"
307
387
  )
308
388
 
309
-
310
389
  @pytest.mark.parametrize(
311
390
  "pythonSourceTarget, expectedFormattedContent",
312
391
  [
@@ -320,22 +399,27 @@ def testWritePythonFormatsAndWritesToFile(
320
399
  ),
321
400
  ]
322
401
  )
323
- def testWritePythonFormatsAndWritesToStream(
324
- pythonSourceTarget: str,
325
- expectedFormattedContent: str
326
- ) -> None:
327
- """Test that writePython formats Python source code and writes it to IO streams."""
328
- streamMemory = io.StringIO()
402
+ def testWritePythonFormatsAndWritesToStream(pythonSourceTarget: str, expectedFormattedContent: str) -> None:
403
+ """Test that writePython formats Python source code and writes it to IO streams.
404
+
405
+ Parameters
406
+ ----------
407
+ pythonSourceTarget : str
408
+ Unformatted python source.
409
+ expectedFormattedContent : str
410
+ Expected formatted content.
411
+
412
+ """
413
+ streamMemory: io.StringIO = io.StringIO()
329
414
  writePython(pythonSourceTarget, streamMemory)
330
415
 
331
- contentActual = streamMemory.getvalue()
416
+ contentActual: str = streamMemory.getvalue()
332
417
  assert contentActual == expectedFormattedContent, (
333
418
  f"\nTesting: `writePython(..., StringIO)`\n"
334
419
  f"Expected content:\n{repr(expectedFormattedContent)}\n"
335
420
  f"Got content:\n{repr(contentActual)}"
336
421
  )
337
422
 
338
-
339
423
  @pytest.mark.parametrize(
340
424
  "pythonSourceTarget, settingsCustom, expectedFormattedContent",
341
425
  [
@@ -357,18 +441,30 @@ def testWritePythonWithCustomSettings(
357
441
  settingsCustom: dict[str, dict[str, object]],
358
442
  expectedFormattedContent: str
359
443
  ) -> None:
360
- """Test that writePython respects custom formatter settings."""
361
- pathFilenameTarget = pathTmpTesting / "customFormattedModule.py"
444
+ """Test that writePython respects custom formatter settings.
445
+
446
+ Parameters
447
+ ----------
448
+ pathTmpTesting : pathlib.Path
449
+ Temporary directory fixture.
450
+ pythonSourceTarget : str
451
+ Unformatted python source.
452
+ settingsCustom : dict[str, dict[str, object]]
453
+ Dictionary of formatter settings.
454
+ expectedFormattedContent : str
455
+ Expected formatted content.
456
+
457
+ """
458
+ pathFilenameTarget: pathlib.Path = pathTmpTesting / "customFormattedModule.py"
362
459
  writePython(pythonSourceTarget, pathFilenameTarget, settingsCustom)
363
460
 
364
- contentActual = pathFilenameTarget.read_text(encoding="utf-8")
461
+ contentActual: str = pathFilenameTarget.read_text(encoding="utf-8")
365
462
  assert contentActual == expectedFormattedContent, (
366
463
  f"\nTesting: `writePython(..., custom settings)`\n"
367
464
  f"Expected content:\n{repr(expectedFormattedContent)}\n"
368
465
  f"Got content:\n{repr(contentActual)}"
369
466
  )
370
467
 
371
-
372
468
  @pytest.mark.parametrize(
373
469
  "pythonSourceTarget",
374
470
  [
@@ -377,12 +473,18 @@ def testWritePythonWithCustomSettings(
377
473
  "def primeFunction():\n return 37\n",
378
474
  ]
379
475
  )
380
- def testWritePythonCreatesNestedDirectories(
381
- pathTmpTesting: pathlib.Path,
382
- pythonSourceTarget: str
383
- ) -> None:
384
- """Test that writePython creates nested directories when writing to files."""
385
- pathFilenameTarget = pathTmpTesting / "nested" / "directories" / "module.py"
476
+ def testWritePythonCreatesNestedDirectories(pathTmpTesting: pathlib.Path, pythonSourceTarget: str) -> None:
477
+ """Test that writePython creates nested directories when writing to files.
478
+
479
+ Parameters
480
+ ----------
481
+ pathTmpTesting : pathlib.Path
482
+ Temporary directory fixture.
483
+ pythonSourceTarget : str
484
+ Python source code.
485
+
486
+ """
487
+ pathFilenameTarget: pathlib.Path = pathTmpTesting / "nested" / "directories" / "module.py"
386
488
  writePython(pythonSourceTarget, pathFilenameTarget)
387
489
 
388
490
  assert pathFilenameTarget.exists(), (
@@ -397,7 +499,6 @@ def testWritePythonCreatesNestedDirectories(
397
499
  f"Got: exists={pathFilenameTarget.parent.exists()}"
398
500
  )
399
501
 
400
-
401
502
  @pytest.mark.parametrize(
402
503
  "pythonSourceTarget, expectedContainsImport",
403
504
  [
@@ -406,23 +507,29 @@ def testWritePythonCreatesNestedDirectories(
406
507
  ("import sys\n\nvalueFibonacci = sys.version\n", "import sys"),
407
508
  ]
408
509
  )
409
- def testWritePythonPreservesUsedImports(
410
- pathTmpTesting: pathlib.Path,
411
- pythonSourceTarget: str,
412
- expectedContainsImport: str
413
- ) -> None:
414
- """Test that writePython preserves imports that are actually used in the code."""
415
- pathFilenameTarget = pathTmpTesting / "preservedImports.py"
510
+ def testWritePythonPreservesUsedImports(pathTmpTesting: pathlib.Path, pythonSourceTarget: str, expectedContainsImport: str) -> None:
511
+ """Test that writePython preserves imports that are actually used in the code.
512
+
513
+ Parameters
514
+ ----------
515
+ pathTmpTesting : pathlib.Path
516
+ Temporary directory fixture.
517
+ pythonSourceTarget : str
518
+ Python source with used imports.
519
+ expectedContainsImport : str
520
+ Import string that should remain.
521
+
522
+ """
523
+ pathFilenameTarget: pathlib.Path = pathTmpTesting / "preservedImports.py"
416
524
  writePython(pythonSourceTarget, pathFilenameTarget)
417
525
 
418
- contentActual = pathFilenameTarget.read_text(encoding="utf-8")
526
+ contentActual: str = pathFilenameTarget.read_text(encoding="utf-8")
419
527
  assert expectedContainsImport in contentActual, (
420
528
  f"\nTesting: `writePython(...)` preserves used imports\n"
421
529
  f"Expected content to contain: {expectedContainsImport}\n"
422
530
  f"Got content:\n{contentActual}"
423
531
  )
424
532
 
425
-
426
533
  @pytest.mark.parametrize(
427
534
  "pythonSourceTarget, expectedNotContainsImport",
428
535
  [
@@ -431,16 +538,23 @@ def testWritePythonPreservesUsedImports(
431
538
  ("import sys\nimport collections\n\nvalueFibonacci = sys.version\n", "import collections"),
432
539
  ]
433
540
  )
434
- def testWritePythonRemovesUnusedImports(
435
- pathTmpTesting: pathlib.Path,
436
- pythonSourceTarget: str,
437
- expectedNotContainsImport: str
438
- ) -> None:
439
- """Test that writePython removes imports that are not used in the code."""
440
- pathFilenameTarget = pathTmpTesting / "removedImports.py"
541
+ def testWritePythonRemovesUnusedImports(pathTmpTesting: pathlib.Path, pythonSourceTarget: str, expectedNotContainsImport: str) -> None:
542
+ """Test that writePython removes imports that are not used in the code.
543
+
544
+ Parameters
545
+ ----------
546
+ pathTmpTesting : pathlib.Path
547
+ Temporary directory fixture.
548
+ pythonSourceTarget : str
549
+ Python source with unused imports.
550
+ expectedNotContainsImport : str
551
+ Import string that should be removed.
552
+
553
+ """
554
+ pathFilenameTarget: pathlib.Path = pathTmpTesting / "removedImports.py"
441
555
  writePython(pythonSourceTarget, pathFilenameTarget)
442
556
 
443
- contentActual = pathFilenameTarget.read_text(encoding="utf-8")
557
+ contentActual: str = pathFilenameTarget.read_text(encoding="utf-8")
444
558
  assert expectedNotContainsImport not in contentActual, (
445
559
  f"\nTesting: `writePython(...)` removes unused imports\n"
446
560
  f"Expected content to NOT contain: {expectedNotContainsImport}\n"