mustel 0.1.0__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.
mustel-0.1.0/LICENSE ADDED
@@ -0,0 +1,31 @@
1
+ Proprietary License
2
+
3
+ Copyright (c) 2025 Ameya Kulkarni, Raunak Nayak
4
+ All Rights Reserved.
5
+
6
+ This software and associated documentation files (the "Software") are the
7
+ proprietary property of the copyright holders. The Software is protected by
8
+ copyright laws and international copyright treaties.
9
+
10
+ TERMS AND CONDITIONS:
11
+
12
+ 1. LICENSE GRANT: You are granted a limited, non-exclusive, non-transferable
13
+ license to install and use the Software for your personal or internal
14
+ business purposes only.
15
+
16
+ 2. RESTRICTIONS: You may NOT:
17
+ - Copy, modify, or create derivative works of the Software
18
+ - Distribute, sublicense, sell, or transfer the Software to any third party
19
+ - Reverse engineer, decompile, or disassemble the Software
20
+ - Remove or alter any proprietary notices on the Software
21
+
22
+ 3. NO WARRANTY: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25
+
26
+ 4. LIMITATION OF LIABILITY: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
28
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
+
31
+ For licensing inquiries, contact: acclaptop47@gmail.com
mustel-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,95 @@
1
+ Metadata-Version: 2.4
2
+ Name: mustel
3
+ Version: 0.1.0
4
+ Summary: Simple Python environment inspector - see what's installed across all your Python versions
5
+ Author: Raunak Nayak
6
+ Author-email: Ameya Kulkarni <acclaptop47@gmail.com>
7
+ License: Proprietary
8
+ Keywords: python,environment,packages,pip,inspector
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: Other/Proprietary License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.8
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Dynamic: license-file
26
+
27
+ # mustel 🦦
28
+
29
+ A simple Python environment inspector. See what's installed across all your Python versions.
30
+
31
+ ## Why?
32
+
33
+ Ever had this happen?
34
+ ```
35
+ pip install numpy
36
+ import numpy # ❌ ModuleNotFoundError
37
+ ```
38
+
39
+ That's because you have multiple Python versions, and `pip` installed it in a different one!
40
+
41
+ **mustel** helps you see exactly what's installed where.
42
+
43
+ ## Install
44
+
45
+ ```bash
46
+ pip install mustel
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ ```bash
52
+ mustel # Show packages in current Python
53
+ mustel all # Show all Python installations
54
+ mustel diff # Compare packages across Pythons
55
+ mustel check X # Check if package X exists
56
+ mustel updates # Show outdated packages
57
+ mustel help # Show help
58
+ ```
59
+
60
+ ## Examples
61
+
62
+ ### See all your Pythons
63
+ ```
64
+ > mustel all
65
+
66
+ 🦦 mustel — all pythons
67
+
68
+ Found 3 Python(s):
69
+
70
+ ------------------------------------------------------------
71
+ ★ Python 3.13.7 (current)
72
+ Path: C:\Users\...\Python313\python.exe
73
+ Packages: 151
74
+
75
+ Python 3.14.0
76
+ Path: C:\Users\...\Python314\python.exe
77
+ Packages: 8
78
+ ------------------------------------------------------------
79
+ ```
80
+
81
+ ### Use with a specific Python
82
+ ```bash
83
+ C:\Python314\python.exe -m mustel
84
+ ```
85
+
86
+ ## Why "mustel"?
87
+
88
+ Named after the **Mustelidae** family (otters, weasels, ferrets) - small but effective hunters that find things in hidden places! 🦦
89
+
90
+ ## License
91
+
92
+ Proprietary - All Rights Reserved.
93
+ Copyright © 2025 Ameya Kulkarni, Raunak Nayak
94
+
95
+ See [LICENSE](LICENSE) for details.
mustel-0.1.0/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # mustel 🦦
2
+
3
+ A simple Python environment inspector. See what's installed across all your Python versions.
4
+
5
+ ## Why?
6
+
7
+ Ever had this happen?
8
+ ```
9
+ pip install numpy
10
+ import numpy # ❌ ModuleNotFoundError
11
+ ```
12
+
13
+ That's because you have multiple Python versions, and `pip` installed it in a different one!
14
+
15
+ **mustel** helps you see exactly what's installed where.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ pip install mustel
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```bash
26
+ mustel # Show packages in current Python
27
+ mustel all # Show all Python installations
28
+ mustel diff # Compare packages across Pythons
29
+ mustel check X # Check if package X exists
30
+ mustel updates # Show outdated packages
31
+ mustel help # Show help
32
+ ```
33
+
34
+ ## Examples
35
+
36
+ ### See all your Pythons
37
+ ```
38
+ > mustel all
39
+
40
+ 🦦 mustel — all pythons
41
+
42
+ Found 3 Python(s):
43
+
44
+ ------------------------------------------------------------
45
+ ★ Python 3.13.7 (current)
46
+ Path: C:\Users\...\Python313\python.exe
47
+ Packages: 151
48
+
49
+ Python 3.14.0
50
+ Path: C:\Users\...\Python314\python.exe
51
+ Packages: 8
52
+ ------------------------------------------------------------
53
+ ```
54
+
55
+ ### Use with a specific Python
56
+ ```bash
57
+ C:\Python314\python.exe -m mustel
58
+ ```
59
+
60
+ ## Why "mustel"?
61
+
62
+ Named after the **Mustelidae** family (otters, weasels, ferrets) - small but effective hunters that find things in hidden places! 🦦
63
+
64
+ ## License
65
+
66
+ Proprietary - All Rights Reserved.
67
+ Copyright © 2025 Ameya Kulkarni, Raunak Nayak
68
+
69
+ See [LICENSE](LICENSE) for details.
File without changes
@@ -0,0 +1,5 @@
1
+ # This file allows running: python -m mustel
2
+ from mustel.main import main
3
+
4
+ if __name__ == "__main__":
5
+ main()
@@ -0,0 +1,327 @@
1
+ # mustel/main.py
2
+ """
3
+ mustel - Simple Python environment inspector
4
+ A tool to see what's installed across all your Python versions.
5
+
6
+ Named after the Mustelidae family (otters, weasels) - small but effective hunters!
7
+ """
8
+ import sys
9
+ import os
10
+ import subprocess
11
+ import json
12
+ import platform
13
+ import importlib.util
14
+
15
+ # Fix Windows console encoding for emojis
16
+ if platform.system() == "Windows":
17
+ try:
18
+ sys.stdout.reconfigure(encoding='utf-8')
19
+ except:
20
+ pass
21
+
22
+
23
+ # ============================================================
24
+ # HELPER FUNCTIONS
25
+ # ============================================================
26
+
27
+ def run_cmd(cmd):
28
+ """Run a command and return output, or None if it fails."""
29
+ try:
30
+ return subprocess.check_output(cmd, stderr=subprocess.DEVNULL, text=True)
31
+ except:
32
+ return None
33
+
34
+
35
+ def get_packages(python_path):
36
+ """Get dict of {package_name: version} for a Python installation."""
37
+ out = run_cmd([python_path, "-m", "pip", "list", "--format=json"])
38
+ if not out:
39
+ return {}
40
+ try:
41
+ data = json.loads(out)
42
+ return {pkg["name"].lower(): pkg["version"] for pkg in data}
43
+ except:
44
+ return {}
45
+
46
+
47
+ def get_outdated(python_path):
48
+ """Get dict of {package_name: (current, latest)} for outdated packages."""
49
+ out = run_cmd([python_path, "-m", "pip", "list", "--outdated", "--format=json"])
50
+ if not out:
51
+ return {}
52
+ try:
53
+ data = json.loads(out)
54
+ return {pkg["name"].lower(): (pkg["version"], pkg["latest_version"]) for pkg in data}
55
+ except:
56
+ return {}
57
+
58
+
59
+ def find_all_pythons():
60
+ """Find all Python installations on the system."""
61
+ found = set()
62
+ current = sys.executable
63
+
64
+ if platform.system() == "Windows":
65
+ # Check common Windows install location
66
+ local_programs = os.path.expandvars(r"%LOCALAPPDATA%\Programs\Python")
67
+ if os.path.exists(local_programs):
68
+ for folder in os.listdir(local_programs):
69
+ exe = os.path.join(local_programs, folder, "python.exe")
70
+ if os.path.exists(exe):
71
+ found.add(exe)
72
+
73
+ # Check where python finds
74
+ out = run_cmd(["where", "python"])
75
+ if out:
76
+ for line in out.splitlines():
77
+ line = line.strip()
78
+ if line.lower().endswith(".exe"):
79
+ found.add(line)
80
+ else:
81
+ # Unix: check python3.x versions
82
+ for minor in range(7, 15):
83
+ out = run_cmd(["which", f"python3.{minor}"])
84
+ if out:
85
+ found.add(out.strip())
86
+
87
+ # Remove current python and normalize paths
88
+ result = []
89
+ current_real = os.path.normcase(os.path.realpath(current))
90
+ seen = set()
91
+
92
+ for path in found:
93
+ try:
94
+ path_real = os.path.normcase(os.path.realpath(path))
95
+ if path_real == current_real:
96
+ continue
97
+ if path_real not in seen:
98
+ seen.add(path_real)
99
+ result.append(path)
100
+ except:
101
+ pass
102
+
103
+ return result
104
+
105
+
106
+ def is_importable(name):
107
+ """Check if a module can be imported."""
108
+ return importlib.util.find_spec(name) is not None
109
+
110
+
111
+ # ============================================================
112
+ # COMMANDS
113
+ # ============================================================
114
+
115
+ def cmd_list():
116
+ """Show packages in current Python."""
117
+ exe = sys.executable
118
+ version = sys.version.split()[0]
119
+
120
+ print(f"\n🦦 mustel — Python {version}\n")
121
+ print(f"Path: {exe}\n")
122
+
123
+ packages = get_packages(exe)
124
+ if packages:
125
+ print(f"📦 {len(packages)} packages installed:\n")
126
+ for name in sorted(packages):
127
+ print(f" {name} == {packages[name]}")
128
+ else:
129
+ print(" (no packages found)")
130
+
131
+
132
+ def cmd_all():
133
+ """Show all Python installations."""
134
+ print("\n🦦 mustel — all pythons\n")
135
+
136
+ current = sys.executable
137
+ others = find_all_pythons()
138
+ all_pythons = [current] + others
139
+
140
+ print(f"Found {len(all_pythons)} Python(s):\n")
141
+ print("-" * 60)
142
+
143
+ for exe in all_pythons:
144
+ # Get version
145
+ out = run_cmd([exe, "--version"])
146
+ version = out.strip() if out else "unknown"
147
+
148
+ # Get package count
149
+ packages = get_packages(exe)
150
+ count = len(packages)
151
+
152
+ # Mark current
153
+ marker = "★" if exe == current else " "
154
+ label = "(current)" if exe == current else ""
155
+
156
+ print(f"{marker} {version} {label}")
157
+ print(f" Path: {exe}")
158
+ print(f" Packages: {count}\n")
159
+
160
+ print("-" * 60)
161
+
162
+
163
+ def cmd_diff():
164
+ """Show packages in other Pythons that aren't in current."""
165
+ print("\n🦦 mustel — diff\n")
166
+
167
+ current = sys.executable
168
+ current_packages = get_packages(current)
169
+ others = find_all_pythons()
170
+
171
+ if not others:
172
+ print("No other Python installations found.")
173
+ return
174
+
175
+ print(f"Current Python: {current}")
176
+ print(f"Packages: {len(current_packages)}\n")
177
+
178
+ for other in others:
179
+ other_packages = get_packages(other)
180
+ if not other_packages:
181
+ continue
182
+
183
+ # Find packages in other that aren't in current
184
+ missing = {k: v for k, v in other_packages.items() if k not in current_packages}
185
+
186
+ out = run_cmd([other, "--version"])
187
+ version = out.strip() if out else other
188
+
189
+ print(f"\n{version}")
190
+ print(f" Path: {other}")
191
+
192
+ if missing:
193
+ print(f" 📦 {len(missing)} unique packages:")
194
+ for name in sorted(missing):
195
+ print(f" {name} == {missing[name]}")
196
+ else:
197
+ print(" ✅ No unique packages")
198
+
199
+
200
+ def cmd_check(package_name):
201
+ """Check if a package exists and where."""
202
+ print(f"\n🦦 mustel — check '{package_name}'\n")
203
+
204
+ current = sys.executable
205
+
206
+ # Check if importable in current
207
+ if is_importable(package_name):
208
+ print(f"✅ '{package_name}' is available in current Python")
209
+ return
210
+
211
+ print(f"❌ '{package_name}' is NOT in current Python ({current})\n")
212
+
213
+ # Search other Pythons
214
+ others = find_all_pythons()
215
+ found_in = []
216
+
217
+ for other in others:
218
+ packages = get_packages(other)
219
+ if package_name.lower() in packages:
220
+ found_in.append((other, packages[package_name.lower()]))
221
+
222
+ if found_in:
223
+ print("Found in:")
224
+ for path, version in found_in:
225
+ print(f" {path} -> {version}")
226
+ print(f"\nTo install: pip install {package_name}")
227
+ else:
228
+ print("Not found in any Python installation.")
229
+
230
+
231
+ def cmd_updates():
232
+ """Show outdated packages."""
233
+ print("\n🦦 mustel — updates\n")
234
+
235
+ current = sys.executable
236
+ print(f"Python: {current}\n")
237
+ print("⏳ Checking... (this takes 1-2 minutes)\n")
238
+
239
+ outdated = get_outdated(current)
240
+
241
+ if not outdated:
242
+ print("✅ All packages are up to date!")
243
+ return
244
+
245
+ print(f"📦 {len(outdated)} updates available:\n")
246
+ for name in sorted(outdated):
247
+ old, new = outdated[name]
248
+ print(f" {name}: {old} → {new}")
249
+
250
+
251
+ def cmd_install(package_name):
252
+ """Install a package using pip."""
253
+ print(f"\n🦦 mustel — install '{package_name}'\n")
254
+
255
+ current = sys.executable
256
+ print(f"Installing to: {current}\n")
257
+
258
+ # Check if already installed
259
+ packages = get_packages(current)
260
+ if package_name.lower() in packages:
261
+ version = packages[package_name.lower()]
262
+ print(f"⚠️ '{package_name}' is already installed (version {version})")
263
+ print(f"\nTo upgrade, run: pip install --upgrade {package_name}")
264
+ return
265
+
266
+ print(f"⏳ Installing {package_name}...\n")
267
+
268
+ # Run pip install (using subprocess.run so output shows in real-time)
269
+ result = subprocess.run(
270
+ [current, "-m", "pip", "install", package_name],
271
+ text=True
272
+ )
273
+
274
+ # Check if it worked
275
+ if result.returncode == 0:
276
+ print(f"\n✅ Successfully installed {package_name}!")
277
+ else:
278
+ print(f"\n❌ Failed to install {package_name}")
279
+ print(" Check the error message above.")
280
+
281
+ def cmd_help():
282
+ """Show help."""
283
+ print("""
284
+ mustel — Python environment inspector
285
+
286
+ Commands:
287
+ mustel Show packages in current Python
288
+ mustel all Show all Python installations
289
+ mustel diff Compare packages across Pythons
290
+ mustel check X Check if package X exists
291
+ mustel install X Install package X
292
+ mustel updates Show outdated packages
293
+ mustel help Show this help
294
+
295
+ Tip: Run with different Python:
296
+ C:\\path\\python.exe -m mustel
297
+ """)
298
+
299
+
300
+ # ============================================================
301
+ # MAIN
302
+ # ============================================================
303
+
304
+ def main():
305
+ args = sys.argv[1:]
306
+
307
+ if not args:
308
+ cmd_list()
309
+ elif args[0] in ("help", "-h", "--help"):
310
+ cmd_help()
311
+ elif args[0] == "all":
312
+ cmd_all()
313
+ elif args[0] == "diff":
314
+ cmd_diff()
315
+ elif args[0] == "check" and len(args) > 1:
316
+ cmd_check(args[1])
317
+ elif args[0] == "updates":
318
+ cmd_updates()
319
+ elif args[0] == "install" and len(args) > 1:
320
+ cmd_install(args[1])
321
+ else:
322
+ print(f"Unknown command: {args[0]}")
323
+ cmd_help()
324
+
325
+
326
+ if __name__ == "__main__":
327
+ main()
@@ -0,0 +1,95 @@
1
+ Metadata-Version: 2.4
2
+ Name: mustel
3
+ Version: 0.1.0
4
+ Summary: Simple Python environment inspector - see what's installed across all your Python versions
5
+ Author: Raunak Nayak
6
+ Author-email: Ameya Kulkarni <acclaptop47@gmail.com>
7
+ License: Proprietary
8
+ Keywords: python,environment,packages,pip,inspector
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: Other/Proprietary License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.8
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Dynamic: license-file
26
+
27
+ # mustel 🦦
28
+
29
+ A simple Python environment inspector. See what's installed across all your Python versions.
30
+
31
+ ## Why?
32
+
33
+ Ever had this happen?
34
+ ```
35
+ pip install numpy
36
+ import numpy # ❌ ModuleNotFoundError
37
+ ```
38
+
39
+ That's because you have multiple Python versions, and `pip` installed it in a different one!
40
+
41
+ **mustel** helps you see exactly what's installed where.
42
+
43
+ ## Install
44
+
45
+ ```bash
46
+ pip install mustel
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ ```bash
52
+ mustel # Show packages in current Python
53
+ mustel all # Show all Python installations
54
+ mustel diff # Compare packages across Pythons
55
+ mustel check X # Check if package X exists
56
+ mustel updates # Show outdated packages
57
+ mustel help # Show help
58
+ ```
59
+
60
+ ## Examples
61
+
62
+ ### See all your Pythons
63
+ ```
64
+ > mustel all
65
+
66
+ 🦦 mustel — all pythons
67
+
68
+ Found 3 Python(s):
69
+
70
+ ------------------------------------------------------------
71
+ ★ Python 3.13.7 (current)
72
+ Path: C:\Users\...\Python313\python.exe
73
+ Packages: 151
74
+
75
+ Python 3.14.0
76
+ Path: C:\Users\...\Python314\python.exe
77
+ Packages: 8
78
+ ------------------------------------------------------------
79
+ ```
80
+
81
+ ### Use with a specific Python
82
+ ```bash
83
+ C:\Python314\python.exe -m mustel
84
+ ```
85
+
86
+ ## Why "mustel"?
87
+
88
+ Named after the **Mustelidae** family (otters, weasels, ferrets) - small but effective hunters that find things in hidden places! 🦦
89
+
90
+ ## License
91
+
92
+ Proprietary - All Rights Reserved.
93
+ Copyright © 2025 Ameya Kulkarni, Raunak Nayak
94
+
95
+ See [LICENSE](LICENSE) for details.
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ mustel/__init__.py
5
+ mustel/__main__.py
6
+ mustel/main.py
7
+ mustel.egg-info/PKG-INFO
8
+ mustel.egg-info/SOURCES.txt
9
+ mustel.egg-info/dependency_links.txt
10
+ mustel.egg-info/entry_points.txt
11
+ mustel.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mustel = mustel.main:main
@@ -0,0 +1 @@
1
+ mustel
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "mustel"
7
+ version = "0.1.0"
8
+ description = "Simple Python environment inspector - see what's installed across all your Python versions"
9
+ requires-python = ">=3.8"
10
+ readme = "README.md"
11
+ license = {text = "Proprietary"}
12
+ authors = [
13
+ {name = "Ameya Kulkarni", email = "acclaptop47@gmail.com"},
14
+ {name = "Raunak Nayak"},
15
+ ]
16
+ keywords = ["python", "environment", "packages", "pip", "inspector"]
17
+ classifiers = [
18
+ "Development Status :: 4 - Beta",
19
+ "Environment :: Console",
20
+ "Intended Audience :: Developers",
21
+ "License :: Other/Proprietary License",
22
+ "Operating System :: OS Independent",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.8",
25
+ "Programming Language :: Python :: 3.9",
26
+ "Programming Language :: Python :: 3.10",
27
+ "Programming Language :: Python :: 3.11",
28
+ "Programming Language :: Python :: 3.12",
29
+ "Programming Language :: Python :: 3.13",
30
+ "Topic :: Software Development :: Libraries :: Python Modules",
31
+ ]
32
+
33
+ [project.scripts]
34
+ mustel = "mustel.main:main"
mustel-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+