pypsx-toolkit 3.0.2__tar.gz → 3.0.3__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.
Files changed (25) hide show
  1. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/PKG-INFO +3 -3
  2. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pyproject.toml +3 -3
  3. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/__init__.py +1 -1
  4. pypsx_toolkit-3.0.3/setup.py +103 -0
  5. pypsx_toolkit-3.0.2/setup.py +0 -70
  6. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/LICENSE +0 -0
  7. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/MANIFEST.in +0 -0
  8. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/README.md +0 -0
  9. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/__init__.pyi +0 -0
  10. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/analysis/__init__.py +0 -0
  11. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/analysis/__init__.pyi +0 -0
  12. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/api.pyi +0 -0
  13. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/core/__init__.py +0 -0
  14. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/core/errors.pyi +0 -0
  15. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/core/stream.pyi +0 -0
  16. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/endpoints/__init__.py +0 -0
  17. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/endpoints/constants.py +0 -0
  18. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/format/__init__.py +0 -0
  19. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/market.pyi +0 -0
  20. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/models.py +0 -0
  21. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/models.pyi +0 -0
  22. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/py.typed +0 -0
  23. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit/ticker.pyi +0 -0
  24. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/pypsx_toolkit.egg-info/SOURCES.txt +0 -0
  25. {pypsx_toolkit-3.0.2 → pypsx_toolkit-3.0.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pypsx-toolkit
3
- Version: 3.0.2
3
+ Version: 3.0.3
4
4
  Summary: Pakistan Stock Exchange (PSX) data library with yfinance-like API
5
5
  Author-email: PyPSX Team <contact@pypsx.dev>
6
6
  Maintainer-email: PyPSX Team <contact@pypsx.dev>
@@ -47,9 +47,9 @@ License-File: LICENSE
47
47
  Requires-Dist: requests>=2.31.0
48
48
  Requires-Dist: beautifulsoup4>=4.12.0
49
49
  Requires-Dist: lxml>=4.9.0
50
- Requires-Dist: pandas>=2.0.0
50
+ Requires-Dist: pandas<2.3.3,>=2.0.0
51
51
  Requires-Dist: loguru>=0.7.0
52
- Requires-Dist: numpy>=1.24.0
52
+ Requires-Dist: numpy<2.3.0,>=1.24.0
53
53
  Provides-Extra: plot
54
54
  Requires-Dist: matplotlib>=3.5.0; extra == "plot"
55
55
  Requires-Dist: seaborn>=0.11.0; extra == "plot"
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pypsx-toolkit"
7
- version = "3.0.2"
7
+ version = "3.0.3"
8
8
  description = "Pakistan Stock Exchange (PSX) data library with yfinance-like API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -38,9 +38,9 @@ dependencies = [
38
38
  "requests>=2.31.0",
39
39
  "beautifulsoup4>=4.12.0",
40
40
  "lxml>=4.9.0",
41
- "pandas>=2.0.0",
41
+ "pandas>=2.0.0,<2.3.3",
42
42
  "loguru>=0.7.0",
43
- "numpy>=1.24.0",
43
+ "numpy>=1.24.0,<2.3.0",
44
44
  ]
45
45
 
46
46
  [project.optional-dependencies]
@@ -2,7 +2,7 @@
2
2
  PSX yfinance-style API
3
3
  """
4
4
 
5
- __version__ = "3.0.2"
5
+ __version__ = "3.0.3"
6
6
  __author__ = "PyPSX Team"
7
7
  __email__ = "pypsx@example.com"
8
8
 
@@ -0,0 +1,103 @@
1
+ """
2
+ Cython build configuration for pypsx.
3
+
4
+ Compiles all implementation modules into platform-specific binary extensions
5
+ (.pyd on Windows, .so on Linux/macOS). __init__.py, models.py, and constants.py
6
+ are intentionally excluded so they remain as plain-text Python re-exporters.
7
+ """
8
+ import os
9
+ import glob
10
+ from setuptools import setup, Extension, find_packages
11
+ from setuptools.command.build_py import build_py as _build_py
12
+ from Cython.Build import cythonize
13
+
14
+ # Stems that must stay as plain Python (pickling, isinstance, re-exports)
15
+ EXCLUDE_STEMS = {"__init__", "constants", "models"}
16
+
17
+ # Folders to skip entirely
18
+ EXCLUDE_DIRS = {"backend", "build", "dist", "tests", "__pycache__", ".git"}
19
+
20
+
21
+ # os.name == "nt" does not imply MSVC -- CC/CXX may point at a mingw
22
+ # toolchain (e.g. w64devkit) for local builds without Visual Studio, and
23
+ # mingw's gcc/g++ reject MSVC-style "/O2" the same way MSVC would reject "-O2".
24
+ _USING_MSVC = os.name == "nt" and "gcc" not in os.environ.get("CC", "").lower()
25
+ _OPT_FLAG = "/O2" if _USING_MSVC else "-O2"
26
+
27
+
28
+ def collect_extensions(pkg_root: str):
29
+ extensions = []
30
+ for path in glob.glob(f"{pkg_root}/**/*.py", recursive=True):
31
+ # Normalise separators
32
+ norm = path.replace("\\", "/")
33
+
34
+ # Skip excluded directories
35
+ parts = norm.split("/")
36
+ if any(p in EXCLUDE_DIRS for p in parts):
37
+ continue
38
+
39
+ stem = os.path.splitext(os.path.basename(path))[0]
40
+ if stem in EXCLUDE_STEMS:
41
+ continue
42
+
43
+ # Convert path to dotted module name (e.g. pypsx/core/fetchers.py -> pypsx.core.fetchers)
44
+ module = norm.replace("/", ".")[:-3]
45
+ extensions.append(
46
+ Extension(
47
+ module,
48
+ [path],
49
+ extra_compile_args=[_OPT_FLAG],
50
+ )
51
+ )
52
+ return extensions
53
+
54
+
55
+ class build_py(_build_py):
56
+ """
57
+ Drop .py source for modules that get Cython-compiled, so wheels ship only
58
+ the compiled extension (+ .pyi stub) for them -- MANIFEST.in's
59
+ include/exclude rules only govern sdist content, NOT bdist_wheel, so
60
+ without this override every wheel ships the full readable .py source
61
+ right alongside the .pyd/.so, silently defeating the whole point of
62
+ compiling in the first place.
63
+ """
64
+
65
+ def find_package_modules(self, package, package_dir):
66
+ modules = super().find_package_modules(package, package_dir)
67
+ return [(pkg, mod, path) for (pkg, mod, path) in modules if mod in EXCLUDE_STEMS]
68
+
69
+
70
+ def main():
71
+ extensions = collect_extensions("pypsx_toolkit")
72
+
73
+ setup(
74
+ cmdclass={"build_py": build_py},
75
+ packages=find_packages(
76
+ exclude=["backend*", "build*", "dist*", "tests*", "*.egg-info*"]
77
+ ),
78
+ ext_modules=cythonize(
79
+ extensions,
80
+ compiler_directives={
81
+ "language_level": "3",
82
+ # binding=True: wraps compiled functions so inspect.signature() works.
83
+ # Required if FastAPI or any DI framework introspects function args.
84
+ "binding": True,
85
+ # embedsignature=True: embeds the Python call signature in the docstring
86
+ # so IDEs can show it even when the .pyi stub is absent.
87
+ "embedsignature": True,
88
+ },
89
+ build_dir="build",
90
+ annotate=False,
91
+ nthreads=4,
92
+ ),
93
+ package_data={"": ["*.pyi", "py.typed"]},
94
+ zip_safe=False,
95
+ )
96
+
97
+
98
+ if __name__ == "__main__":
99
+ # cythonize(nthreads=4) spawns a multiprocessing pool. On Windows
100
+ # (spawn start method) child processes reimport this file as __main__;
101
+ # without this guard, each child re-enters main() and re-spawns its own
102
+ # pool, crashing the whole build with BrokenProcessPool.
103
+ main()
@@ -1,70 +0,0 @@
1
- """
2
- Cython build configuration for pypsx.
3
-
4
- Compiles all implementation modules into platform-specific binary extensions
5
- (.pyd on Windows, .so on Linux/macOS). __init__.py, models.py, and constants.py
6
- are intentionally excluded so they remain as plain-text Python re-exporters.
7
- """
8
- import os
9
- import glob
10
- from setuptools import setup, Extension, find_packages
11
- from Cython.Build import cythonize
12
-
13
- # Stems that must stay as plain Python (pickling, isinstance, re-exports)
14
- EXCLUDE_STEMS = {"__init__", "constants", "models"}
15
-
16
- # Folders to skip entirely
17
- EXCLUDE_DIRS = {"backend", "build", "dist", "tests", "__pycache__", ".git"}
18
-
19
-
20
- def collect_extensions(pkg_root: str):
21
- extensions = []
22
- for path in glob.glob(f"{pkg_root}/**/*.py", recursive=True):
23
- # Normalise separators
24
- norm = path.replace("\\", "/")
25
-
26
- # Skip excluded directories
27
- parts = norm.split("/")
28
- if any(p in EXCLUDE_DIRS for p in parts):
29
- continue
30
-
31
- stem = os.path.splitext(os.path.basename(path))[0]
32
- if stem in EXCLUDE_STEMS:
33
- continue
34
-
35
- # Convert path to dotted module name (e.g. pypsx/core/fetchers.py -> pypsx.core.fetchers)
36
- module = norm.replace("/", ".")[:-3]
37
- extensions.append(
38
- Extension(
39
- module,
40
- [path],
41
- extra_compile_args=["/O2"] if os.name == "nt" else ["-O2"],
42
- )
43
- )
44
- return extensions
45
-
46
-
47
- extensions = collect_extensions("pypsx_toolkit")
48
-
49
- setup(
50
- packages=find_packages(
51
- exclude=["backend*", "build*", "dist*", "tests*", "*.egg-info*"]
52
- ),
53
- ext_modules=cythonize(
54
- extensions,
55
- compiler_directives={
56
- "language_level": "3",
57
- # binding=True: wraps compiled functions so inspect.signature() works.
58
- # Required if FastAPI or any DI framework introspects function args.
59
- "binding": True,
60
- # embedsignature=True: embeds the Python call signature in the docstring
61
- # so IDEs can show it even when the .pyi stub is absent.
62
- "embedsignature": True,
63
- },
64
- build_dir="build",
65
- annotate=False,
66
- nthreads=4,
67
- ),
68
- package_data={"": ["*.pyi", "py.typed"]},
69
- zip_safe=False,
70
- )
File without changes
File without changes
File without changes
File without changes