From e2f8ea7b6768183fc7348a8b2dd70c54fb971d54 Mon Sep 17 00:00:00 2001 From: Fierelier Date: Mon, 19 Dec 2022 08:01:04 +0100 Subject: [PATCH] Initial commit --- .gitignore | 1 + LICENSE | 19 ++++++++ example.py | 35 ++++++++++++++ modmfp/test.py | 4 ++ modpy/me/fier/python/__init__.py | 78 ++++++++++++++++++++++++++++++++ readme.txt | 28 ++++++++++++ 6 files changed, 165 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 example.py create mode 100644 modmfp/test.py create mode 100644 modpy/me/fier/python/__init__.py create mode 100644 readme.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed8ebf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..de7807f --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2022 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/example.py b/example.py new file mode 100644 index 0000000..5959ca2 --- /dev/null +++ b/example.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +def init(): pass +def main(): + mfp.setProgramName("me.fier.example") # Your domain/username and the name of your program + + # Some example code to test the functionality + testpy = mfp.require("test") + testpy.st = "Hello world" + testpy.echo() + testpy["st"] = "Hello world 2" + testpy.echo() + testpy = mfp.require("test") + testpy.echo() + testpy = mfp.dofile(mfp.p(mfp.sd,"modmfp","test.py")) # Same file as used for mfp.require + testpy.echo() + +def bootstrap(name,modName): + if name in globals(): return + import sys, os, importlib + if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): + s = os.path.realpath(sys.executable) + else: + s = os.path.realpath(__file__) + + if not os.path.join(os.path.dirname(s),"modpy") in sys.path: + sys.path = [os.path.join(os.path.dirname(s),"modpy")] + sys.path + + mod = importlib.import_module(modName); modl = mod.Bunch() + mod.init(mod,modl,s,name) + globals()[name] = mod; globals()[name + "l"] = modl + +bootstrap("mfp","me.fier.python") +init() +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/modmfp/test.py b/modmfp/test.py new file mode 100644 index 0000000..461ca4b --- /dev/null +++ b/modmfp/test.py @@ -0,0 +1,4 @@ +print("Running " +mfpl.s) +st = None +def echo(): + print(st) \ No newline at end of file diff --git a/modpy/me/fier/python/__init__.py b/modpy/me/fier/python/__init__.py new file mode 100644 index 0000000..9e93416 --- /dev/null +++ b/modpy/me/fier/python/__init__.py @@ -0,0 +1,78 @@ +import os + +# BUNCH +try: + import munch + Bunch = munch.Munch + bunchify = munch.munchify + unbunchify = munch.unmunchify +except Exception: + import bunch + Bunch = munch.Bunch + bunchify = munch.bunchify + unbunchify = munch.unbunchify + +# GLOBALS +g = Bunch() + +# SCRIPTS +paths = [] +loaded = Bunch() + +def docode(st,name = "Unknown"): + code = compile(st,name,"exec") + glb = Bunch() + glb[distro] = me + glb[distro + "l"] = Bunch() + glb[distro + "l"].s = name + try: + glb[distro + "l"].sd = pUp(name) + except Exception: + pass + exec(code,glb) + return glb + +def dofile(path): + return docode(open(path,encoding="utf-8").read(),path) + +def require(name,*args,**kwargs): + if not name in loaded: + for path in paths: + path = path.replace("?",name) + if os.path.isfile(path): + loaded[name] = dofile(path,*args,**kwargs) + return loaded[name] + raise Exception("Library " +name+ " not found.") + return loaded[name] + +# PROGRAM +programName = None +programNameSet = False +def setProgramName(name): + global programName,programNameSet + if programNameSet: return + programNameSet = True + programName = name + +# INIT +inited = False +def init(mod,modl,sp,d): + global inited + if inited: return + global distro,me,p,pUp,programName,programNameSet,s,sd,distro + import sys + inited = True + distro = d + me = mod + + p = os.path.join + pUp = os.path.dirname + s = sp + sd = pUp(sp) + modl.s = s + modl.sd = sd + programName = distro + "." + s.replace(modl.sd + os.path.sep,"",1).rsplit(".",1)[0] + programNameSet = False + + paths.append(p(modl.sd,"mod" +distro, "?.py")) + paths.append(p(modl.sd,"mod" +distro, "?","main.py")) \ No newline at end of file diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..77c2eb5 --- /dev/null +++ b/readme.txt @@ -0,0 +1,28 @@ +This is the script most of my future (2022.12.19+) Python projects will be based off of. Some of it is inspired by Lua. + +Compatible with Python 3.4 and up. Lower may work. + +The initialization works like this: +1. bootstrap(globName,modName) is ran -- It initializes the mfp module, which contains all extra functionality. It takes 2 arguments, the name the module will be in global, and the name of the module. Preferably, you do not edit this. +2. init() is ran -- This where you write you initialization code, if your script is usable as a module. +3. main() is ran, if your script is not an import -- This is where you put your program code, if it is one. + +Provides the following mfpl.* (local to current script): +* s: The script's full path. +* sd: The script's full directory. + +Provides the following mfp.* (global to all scripts): +* s: The main script's full path. +* sd: The main script's full directory. +* p(pathList): Combines a list into a path string. +* pUp(path): Goes up (..) in the path. +* setProgramName(name): Set the name of your main program, only works on first call. You should run it before running any other mfp modules. +* programName: The name of your program. DO NOT modify this variable directly, use mfp.setProgramName(). +* require(name): Runs a module from mfp.paths, saves its global, and returns the script's global as a Bunch. If a module of the same name has already been required, it returns the already saved global. +* paths: The directories mfp should search for modules in with mfp.require(). ? in all paths is replaced with the name given to mfp.require(). +* dofile(path): Runs a script from a raw path. It does not use mfp.paths. Returns the script's global as a Bunch. +* docode(text): Runs string as Python code. Returns the script's global as a Bunch. +* g: A Bunch where you can store variables accessible by all mfp modules and scripts. +* Bunch(): Creates a Bunch. Read about it here: https://github.com/Infinidat/munch +* bunchify(list): Converts a list into a Bunch. +* unbunchify(Bunch): Converts a Bunch into a regular list. \ No newline at end of file