polyapi-python 0.3.18.dev3__tar.gz → 0.3.18.dev5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/PKG-INFO +2 -2
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/poly_schemas.py +42 -3
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi_python.egg-info/PKG-INFO +2 -2
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi_python.egg-info/SOURCES.txt +1 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi_python.egg-info/requires.txt +1 -1
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/pyproject.toml +2 -2
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_poly_custom.py +18 -1
- polyapi_python-0.3.18.dev5/tests/test_poly_schemas.py +124 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/LICENSE +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/README.md +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/__init__.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/__main__.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/api.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/auth.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/cli.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/cli_constants.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/client.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/config.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/constants.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/deployables.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/error_handler.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/exceptions.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/execute.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/function_cli.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/generate.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/http_client.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/parser.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/poly_tables.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/prepare.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/py.typed +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/rendered_spec.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/schema.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/server.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/sync.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/typedefs.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/utils.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/variables.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi/webhook.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi_python.egg-info/dependency_links.txt +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi_python.egg-info/top_level.txt +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/setup.cfg +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_api.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_async_proof.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_auth.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_deployables.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_generate.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_parser.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_rendered_spec.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_schema.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_server.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_tabi.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_utils.py +0 -0
- {polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/tests/test_variables.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: polyapi-python
|
|
3
|
-
Version: 0.3.18.
|
|
3
|
+
Version: 0.3.18.dev5
|
|
4
4
|
Summary: The Python Client for PolyAPI, the IPaaS by Developers for Developers
|
|
5
5
|
Author-email: PolyAPI <support@polyapi.io>
|
|
6
6
|
License: MIT License
|
|
@@ -32,7 +32,7 @@ Requires-Dist: requests==2.32.3
|
|
|
32
32
|
Requires-Dist: typing_extensions==4.12.2
|
|
33
33
|
Requires-Dist: jsonschema-gentypes==2.10.0
|
|
34
34
|
Requires-Dist: pydantic==2.8.0
|
|
35
|
-
Requires-Dist: stdlib_list==0.
|
|
35
|
+
Requires-Dist: stdlib_list==0.11.1
|
|
36
36
|
Requires-Dist: colorama==0.4.4
|
|
37
37
|
Requires-Dist: python-socketio[asyncio_client]==5.11.1
|
|
38
38
|
Requires-Dist: truststore==0.8.0
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import re
|
|
2
3
|
import logging
|
|
3
4
|
import tempfile
|
|
4
5
|
import shutil
|
|
5
|
-
from typing import Any, Dict, List, Tuple
|
|
6
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
6
7
|
|
|
7
8
|
from polyapi.schema import wrapped_generate_schema_types
|
|
8
9
|
from polyapi.utils import add_import_to_init, init_the_init, to_func_namespace
|
|
@@ -23,7 +24,7 @@ FALLBACK_SPEC_TEMPLATE = """class {name}(TypedDict, total=False):
|
|
|
23
24
|
"""
|
|
24
25
|
|
|
25
26
|
|
|
26
|
-
def generate_schemas(specs: List[SchemaSpecDto], limit_ids: List[str] = None):
|
|
27
|
+
def generate_schemas(specs: List[SchemaSpecDto], limit_ids: Optional[List[str]] = None):
|
|
27
28
|
failed_schemas = []
|
|
28
29
|
successful_schemas = []
|
|
29
30
|
if limit_ids:
|
|
@@ -209,6 +210,44 @@ def add_schema_to_init(full_path: str, spec: SchemaSpecDto):
|
|
|
209
210
|
f.write(render_poly_schema(spec) + "\n\n")
|
|
210
211
|
|
|
211
212
|
|
|
213
|
+
def _fix_typed_dict_imports(code: str) -> str:
|
|
214
|
+
"""Move TypedDict/NotRequired from `typing` to `typing_extensions` in generated code.
|
|
215
|
+
|
|
216
|
+
jsonschema_gentypes spits out `from typing import ..., TypedDict, ...` which makes
|
|
217
|
+
typing._TypedDictMeta instances. The deploy validator wants typing_extensions.TypedDict,
|
|
218
|
+
so let's rewrite the imports here before writing schema files to disk.
|
|
219
|
+
"""
|
|
220
|
+
lines = code.split('\n')
|
|
221
|
+
new_lines = []
|
|
222
|
+
has_te_import = False
|
|
223
|
+
|
|
224
|
+
for line in lines:
|
|
225
|
+
if re.match(r'from\s+typing_extensions\s+import', line):
|
|
226
|
+
has_te_import = True
|
|
227
|
+
# Ensure TypedDict and NotRequired are in the existing typing_extensions line
|
|
228
|
+
name_set = {n.strip() for n in line.split('import', 1)[1].split(',')}
|
|
229
|
+
name_set |= {'TypedDict', 'NotRequired'}
|
|
230
|
+
new_lines.append(f"from typing_extensions import {', '.join(sorted(name_set))}")
|
|
231
|
+
continue
|
|
232
|
+
|
|
233
|
+
if re.match(r'from\s+typing\s+import', line):
|
|
234
|
+
# Strip TypedDict and NotRequired from the typing import
|
|
235
|
+
names_str = line.split('import', 1)[1]
|
|
236
|
+
names: list[str] = [n.strip() for n in names_str.split(',')]
|
|
237
|
+
names = [n for n in names if n not in ('TypedDict', 'NotRequired', '')]
|
|
238
|
+
if names:
|
|
239
|
+
new_lines.append(f"from typing import {', '.join(names)}")
|
|
240
|
+
# drop the line entirely if nothing is left
|
|
241
|
+
continue
|
|
242
|
+
|
|
243
|
+
new_lines.append(line)
|
|
244
|
+
|
|
245
|
+
result = '\n'.join(new_lines)
|
|
246
|
+
if not has_te_import:
|
|
247
|
+
result = 'from typing_extensions import NotRequired, TypedDict\n' + result
|
|
248
|
+
return result
|
|
249
|
+
|
|
250
|
+
|
|
212
251
|
def render_poly_schema(spec: SchemaSpecDto) -> str:
|
|
213
252
|
definition = spec["definition"]
|
|
214
253
|
if not definition.get("type"):
|
|
@@ -216,5 +255,5 @@ def render_poly_schema(spec: SchemaSpecDto) -> str:
|
|
|
216
255
|
root, schema_types = wrapped_generate_schema_types(
|
|
217
256
|
definition, root=spec["name"], fallback_type=Dict
|
|
218
257
|
)
|
|
219
|
-
return schema_types
|
|
258
|
+
return _fix_typed_dict_imports(schema_types)
|
|
220
259
|
# return FALLBACK_SPEC_TEMPLATE.format(name=spec["name"])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: polyapi-python
|
|
3
|
-
Version: 0.3.18.
|
|
3
|
+
Version: 0.3.18.dev5
|
|
4
4
|
Summary: The Python Client for PolyAPI, the IPaaS by Developers for Developers
|
|
5
5
|
Author-email: PolyAPI <support@polyapi.io>
|
|
6
6
|
License: MIT License
|
|
@@ -32,7 +32,7 @@ Requires-Dist: requests==2.32.3
|
|
|
32
32
|
Requires-Dist: typing_extensions==4.12.2
|
|
33
33
|
Requires-Dist: jsonschema-gentypes==2.10.0
|
|
34
34
|
Requires-Dist: pydantic==2.8.0
|
|
35
|
-
Requires-Dist: stdlib_list==0.
|
|
35
|
+
Requires-Dist: stdlib_list==0.11.1
|
|
36
36
|
Requires-Dist: colorama==0.4.4
|
|
37
37
|
Requires-Dist: python-socketio[asyncio_client]==5.11.1
|
|
38
38
|
Requires-Dist: truststore==0.8.0
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "polyapi-python"
|
|
7
|
-
version = "0.3.18.
|
|
7
|
+
version = "0.3.18.dev5"
|
|
8
8
|
description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers"
|
|
9
9
|
authors = [{ name = "PolyAPI", email = "support@polyapi.io" }]
|
|
10
10
|
dependencies = [
|
|
@@ -12,7 +12,7 @@ dependencies = [
|
|
|
12
12
|
"typing_extensions==4.12.2",
|
|
13
13
|
"jsonschema-gentypes==2.10.0",
|
|
14
14
|
"pydantic==2.8.0",
|
|
15
|
-
"stdlib_list==0.
|
|
15
|
+
"stdlib_list==0.11.1",
|
|
16
16
|
"colorama==0.4.4",
|
|
17
17
|
"python-socketio[asyncio_client]==5.11.1",
|
|
18
18
|
"truststore==0.8.0",
|
|
@@ -7,7 +7,16 @@ from concurrent.futures import ThreadPoolExecutor
|
|
|
7
7
|
def _reload_polyapi():
|
|
8
8
|
sys.modules.pop("polyapi", None)
|
|
9
9
|
sys.modules.pop("polyapi.cli", None)
|
|
10
|
-
|
|
10
|
+
polyapi = importlib.import_module("polyapi")
|
|
11
|
+
|
|
12
|
+
for module_name, module in list(sys.modules.items()):
|
|
13
|
+
if not module_name.startswith("polyapi.") or module_name == "polyapi.cli":
|
|
14
|
+
continue
|
|
15
|
+
submodule_name = module_name.removeprefix("polyapi.")
|
|
16
|
+
if "." not in submodule_name:
|
|
17
|
+
setattr(polyapi, submodule_name, module)
|
|
18
|
+
|
|
19
|
+
return polyapi
|
|
11
20
|
|
|
12
21
|
|
|
13
22
|
def test_import_polyapi_does_not_import_cli():
|
|
@@ -24,6 +33,14 @@ def test_cli_constants_shared_between_runtime_and_cli():
|
|
|
24
33
|
assert tuple(cli_module.CLI_COMMANDS) == cli_constants.CLI_COMMANDS
|
|
25
34
|
|
|
26
35
|
|
|
36
|
+
def test_reload_preserves_existing_submodule_bindings():
|
|
37
|
+
rendered_spec = importlib.import_module("polyapi.rendered_spec")
|
|
38
|
+
|
|
39
|
+
polyapi = _reload_polyapi()
|
|
40
|
+
|
|
41
|
+
assert polyapi.rendered_spec is rendered_spec
|
|
42
|
+
|
|
43
|
+
|
|
27
44
|
def test_poly_custom_nested_scopes_restore_previous_state():
|
|
28
45
|
polyapi = _reload_polyapi()
|
|
29
46
|
poly_custom = polyapi.polyCustom
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from polyapi.poly_schemas import _fix_typed_dict_imports
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestFixTypedDictImports(unittest.TestCase):
|
|
7
|
+
"""Tests for _fix_typed_dict_imports, which rewrites TypedDict/NotRequired
|
|
8
|
+
from `typing` to `typing_extensions` in jsonschema_gentypes output."""
|
|
9
|
+
|
|
10
|
+
# TypedDict moved out of `typing`
|
|
11
|
+
|
|
12
|
+
def test_typeddict_removed_from_typing_import(self):
|
|
13
|
+
code = "from typing import Union, List, TypedDict\n\nclass Foo(TypedDict):\n x: int"
|
|
14
|
+
result = _fix_typed_dict_imports(code)
|
|
15
|
+
self.assertNotIn("from typing import Union, List, TypedDict", result)
|
|
16
|
+
self.assertNotIn("TypedDict", result.split("from typing_extensions")[0].split("from typing")[-1] if "from typing import" in result else "")
|
|
17
|
+
|
|
18
|
+
def test_typeddict_present_in_typing_extensions(self):
|
|
19
|
+
code = "from typing import Union, List, TypedDict\n\nclass Foo(TypedDict):\n x: int"
|
|
20
|
+
result = _fix_typed_dict_imports(code)
|
|
21
|
+
self.assertIn("from typing_extensions import", result)
|
|
22
|
+
self.assertIn("TypedDict", result)
|
|
23
|
+
|
|
24
|
+
def test_notrequired_removed_from_typing_import(self):
|
|
25
|
+
code = "from typing import Union, List, TypedDict, NotRequired\n\nclass Foo(TypedDict):\n x: int"
|
|
26
|
+
result = _fix_typed_dict_imports(code)
|
|
27
|
+
# NotRequired must NOT appear in a `from typing import` line
|
|
28
|
+
for line in result.splitlines():
|
|
29
|
+
if line.startswith("from typing import"):
|
|
30
|
+
self.assertNotIn("NotRequired", line)
|
|
31
|
+
|
|
32
|
+
def test_notrequired_present_in_typing_extensions(self):
|
|
33
|
+
code = "from typing import Union, TypedDict, NotRequired\n\nclass Foo(TypedDict):\n x: NotRequired[int]"
|
|
34
|
+
result = _fix_typed_dict_imports(code)
|
|
35
|
+
self.assertIn("NotRequired", result)
|
|
36
|
+
te_line = next(l for l in result.splitlines() if "from typing_extensions import" in l)
|
|
37
|
+
self.assertIn("NotRequired", te_line)
|
|
38
|
+
|
|
39
|
+
# Remaining typing imports preserved
|
|
40
|
+
|
|
41
|
+
def test_other_typing_names_kept(self):
|
|
42
|
+
code = "from typing import Union, List, TypedDict, Optional"
|
|
43
|
+
result = _fix_typed_dict_imports(code)
|
|
44
|
+
typing_line = next((l for l in result.splitlines() if l.startswith("from typing import")), "")
|
|
45
|
+
self.assertIn("Union", typing_line)
|
|
46
|
+
self.assertIn("List", typing_line)
|
|
47
|
+
self.assertIn("Optional", typing_line)
|
|
48
|
+
|
|
49
|
+
def test_typing_line_dropped_when_only_typeddict(self):
|
|
50
|
+
# If TypedDict was the only import, the `from typing import` line should be gone
|
|
51
|
+
code = "from typing import TypedDict\n\nclass Foo(TypedDict):\n pass"
|
|
52
|
+
result = _fix_typed_dict_imports(code)
|
|
53
|
+
self.assertNotIn("from typing import", result)
|
|
54
|
+
|
|
55
|
+
# Existing typing_extensions import is merged, not duplicated
|
|
56
|
+
|
|
57
|
+
def test_existing_te_import_gets_typeddict_merged(self):
|
|
58
|
+
code = (
|
|
59
|
+
"from typing import Union, TypedDict\n"
|
|
60
|
+
"from typing_extensions import NotRequired\n"
|
|
61
|
+
"\nclass Foo(TypedDict):\n x: NotRequired[int]"
|
|
62
|
+
)
|
|
63
|
+
result = _fix_typed_dict_imports(code)
|
|
64
|
+
te_lines = [l for l in result.splitlines() if "from typing_extensions import" in l]
|
|
65
|
+
self.assertEqual(len(te_lines), 1, "Should have exactly one typing_extensions import line")
|
|
66
|
+
self.assertIn("TypedDict", te_lines[0])
|
|
67
|
+
self.assertIn("NotRequired", te_lines[0])
|
|
68
|
+
|
|
69
|
+
def test_no_duplicate_typing_extensions_line(self):
|
|
70
|
+
code = (
|
|
71
|
+
"from typing_extensions import NotRequired\n"
|
|
72
|
+
"from typing import List, TypedDict\n"
|
|
73
|
+
)
|
|
74
|
+
result = _fix_typed_dict_imports(code)
|
|
75
|
+
te_lines = [l for l in result.splitlines() if "from typing_extensions import" in l]
|
|
76
|
+
self.assertEqual(len(te_lines), 1)
|
|
77
|
+
|
|
78
|
+
# No existing typing_extensions import — one is prepended
|
|
79
|
+
|
|
80
|
+
def test_te_import_prepended_when_absent(self):
|
|
81
|
+
code = "from typing import Union, TypedDict\n\nclass Foo(TypedDict):\n pass"
|
|
82
|
+
result = _fix_typed_dict_imports(code)
|
|
83
|
+
first_meaningful = next(l for l in result.splitlines() if l.strip())
|
|
84
|
+
self.assertIn("from typing_extensions import", first_meaningful)
|
|
85
|
+
|
|
86
|
+
# Code with no TypedDict at all is left structurally intact
|
|
87
|
+
|
|
88
|
+
def test_code_without_typeddict_unchanged_structure(self):
|
|
89
|
+
code = "from typing import Union, List\n\nx: List[int] = []"
|
|
90
|
+
result = _fix_typed_dict_imports(code)
|
|
91
|
+
# typing_extensions is prepended (no existing te import)
|
|
92
|
+
self.assertIn("from typing_extensions import", result)
|
|
93
|
+
# original typing import preserved
|
|
94
|
+
self.assertIn("from typing import Union, List", result)
|
|
95
|
+
# original assignment preserved
|
|
96
|
+
self.assertIn("x: List[int] = []", result)
|
|
97
|
+
|
|
98
|
+
def test_code_with_no_imports_gets_te_prepended(self):
|
|
99
|
+
code = "x = 1\ny = 2"
|
|
100
|
+
result = _fix_typed_dict_imports(code)
|
|
101
|
+
self.assertTrue(result.startswith("from typing_extensions import"))
|
|
102
|
+
|
|
103
|
+
# The rewrite doesn't break class bodies that use TypedDict
|
|
104
|
+
|
|
105
|
+
def test_typeddict_class_body_preserved(self):
|
|
106
|
+
code = (
|
|
107
|
+
"from typing import Union, List, TypedDict\n"
|
|
108
|
+
"\nclass Item(TypedDict):\n"
|
|
109
|
+
" name: str\n"
|
|
110
|
+
" value: Union[int, None]\n"
|
|
111
|
+
)
|
|
112
|
+
result = _fix_typed_dict_imports(code)
|
|
113
|
+
self.assertIn("class Item(TypedDict):", result)
|
|
114
|
+
self.assertIn("name: str", result)
|
|
115
|
+
self.assertIn("value: Union[int, None]", result)
|
|
116
|
+
|
|
117
|
+
def test_empty_string_input(self):
|
|
118
|
+
result = _fix_typed_dict_imports("")
|
|
119
|
+
# Should at minimum prepend the typing_extensions import
|
|
120
|
+
self.assertIn("from typing_extensions import", result)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
if __name__ == "__main__":
|
|
124
|
+
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{polyapi_python-0.3.18.dev3 → polyapi_python-0.3.18.dev5}/polyapi_python.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|