From b4aee3f504e6ad957b7091cd267d1b0a922ca5d7 Mon Sep 17 00:00:00 2001 From: Brandon Rodriguez <brodriguez8774@gmail.com> Date: Fri, 15 Nov 2019 02:25:15 -0500 Subject: [PATCH] Generally rework project imports to be more library friendly --- __init__.py | 22 ++++++++++++++++++++++ documents/references.md | 7 +++++++ resources/basic_graph/edge.py | 20 ++++++++++++++++---- resources/basic_graph/graph.py | 20 ++++++++++++++++---- resources/basic_graph/node.py | 20 ++++++++++++++++---- resources/directed_graph/edge.py | 18 +++++++++++++++--- resources/directed_graph/graph.py | 18 +++++++++++++++--- resources/directed_graph/node.py | 18 +++++++++++++++--- resources/state_machine/edge.py | 18 +++++++++++++++--- resources/state_machine/graph.py | 19 +++++++++++++++---- resources/state_machine/node.py | 18 +++++++++++++++--- 11 files changed, 167 insertions(+), 31 deletions(-) diff --git a/__init__.py b/__init__.py index e69de29..eb5e7d3 100644 --- a/__init__.py +++ b/__init__.py @@ -0,0 +1,22 @@ +""" +Library base importing definitions. +""" + +# Import files/values we want to be available to library users. +from .resources.basic_graph.edge import Edge as BasicEdge +from .resources.basic_graph.node import Node as BasicNode +from .resources.basic_graph.graph import Graph as BasicGraph +from .resources.directed_graph.edge import Edge as DirectedEdge +from .resources.directed_graph.node import Node as DirectedNode +from .resources.directed_graph.graph import Graph as DirectedGraph +from .resources.state_machine.edge import Edge as StateMachineEdge +from .resources.state_machine.node import Node as StateMachineNode +from .resources.state_machine.graph import Graph as StateMachineGraph + + +# Define imports when using the * flag on this library. +__all__ = [ + BasicEdge, BasicNode, BasicGraph, + DirectedEdge, DirectedNode, DirectedGraph, + StateMachineEdge, StateMachineNode, StateMachineGraph, +] diff --git a/documents/references.md b/documents/references.md index 1569029..18f386e 100644 --- a/documents/references.md +++ b/documents/references.md @@ -8,6 +8,13 @@ All references to external logic. Includes anything from stack overflow links to ## New References References new to this project. +### Python Project as a Library +Various recommendations for using a project as a library for other projects: +* Don't configure extra handlers inside the library: <https://docs.python-guide.org/writing/logging/> +* General Library Rules, Mostly Concerning \_\_init\_\_.py: +<https://axialcorps.wordpress.com/2013/08/29/5-simple-rules-for-building-great-python-packages/> +* Many Recommendations for Project Structure: <https://docs.python-guide.org/writing/structure/> + ### Git Submodules Since I don't know how Python projects are exported to be a pip library (and I'm not even sure if that's a good use case for this project), it's being set up as a submodule project for now. diff --git a/resources/basic_graph/edge.py b/resources/basic_graph/edge.py index 4d40220..57de3be 100644 --- a/resources/basic_graph/edge.py +++ b/resources/basic_graph/edge.py @@ -14,15 +14,27 @@ Essentially the "node connection" in a Graph data structure. # User Class Imports. import resources.basic_graph.node as basic_node -from resources import logging as init_logging -# Initialize Logger. -logger = init_logging.get_logger(__name__) +# Initialize logging. +# Since this is a library, we specifically only modify logging if the library is being run alone. +try: + # First, try to import the variable specific to our library logging. + from resources.logging import graph_library_logger + + # It worked, so we know the project is being run stand alone, probably as a unittest. + # Proceed to configure logging. + from resources.logging import get_logger as init_logging + logger = init_logging(__name__) +except ModuleNotFoundError: + # Above import failed. Project is being run as a library. + # Just import existing logger and do not modify. + import logging as init_logging + logger = init_logging.getLogger('graph_library') class Edge(): - def __init__(self, name): + def __init__(self, name, *args, **kwargs): # Check for passed arg types. if name is None: raise TypeError('Edge must be passed a string-convertable name.') diff --git a/resources/basic_graph/graph.py b/resources/basic_graph/graph.py index c890249..34a7a32 100644 --- a/resources/basic_graph/graph.py +++ b/resources/basic_graph/graph.py @@ -15,15 +15,27 @@ from random import randint # User Class Imports. import resources.basic_graph.edge as basic_edge import resources.basic_graph.node as basic_node -from resources import logging as init_logging -# Initialize Logger. -logger = init_logging.get_logger(__name__) +# Initialize logging. +# Since this is a library, we specifically only modify logging if the library is being run alone. +try: + # First, try to import the variable specific to our library logging. + from resources.logging import graph_library_logger + + # It worked, so we know the project is being run stand alone, probably as a unittest. + # Proceed to configure logging. + from resources.logging import get_logger as init_logging + logger = init_logging(__name__) +except ModuleNotFoundError: + # Above import failed. Project is being run as a library. + # Just import existing logger and do not modify. + import logging as init_logging + logger = init_logging.getLogger('graph_library') class Graph(): - def __init__(self): + def __init__(self, *args, **kwargs): # Lists of nodes and edges in graph. self._edges = {} self._nodes = {} diff --git a/resources/basic_graph/node.py b/resources/basic_graph/node.py index 2dfdb50..a811174 100644 --- a/resources/basic_graph/node.py +++ b/resources/basic_graph/node.py @@ -14,15 +14,27 @@ Essentially the "vertex" in a Graph data structure. # User Class Imports. import resources.basic_graph.edge as basic_edge -from resources import logging as init_logging -# Initialize Logger. -logger = init_logging.get_logger(__name__) +# Initialize logging. +# Since this is a library, we specifically only modify logging if the library is being run alone. +try: + # First, try to import the variable specific to our library logging. + from resources.logging import graph_library_logger + + # It worked, so we know the project is being run stand alone, probably as a unittest. + # Proceed to configure logging. + from resources.logging import get_logger as init_logging + logger = init_logging(__name__) +except ModuleNotFoundError: + # Above import failed. Project is being run as a library. + # Just import existing logger and do not modify. + import logging as init_logging + logger = init_logging.getLogger('graph_library') class Node(): - def __init__(self, name): + def __init__(self, name, *args, **kwargs): # Check for passed arg types. if name is None: raise TypeError('Node must be passed a string-convertable name.') diff --git a/resources/directed_graph/edge.py b/resources/directed_graph/edge.py index 4302a25..0f1efef 100644 --- a/resources/directed_graph/edge.py +++ b/resources/directed_graph/edge.py @@ -15,11 +15,23 @@ Essentially the "node connection" in a Graph data structure. # User Class Imports. import resources.basic_graph.edge as basic_edge import resources.directed_graph.node as directed_node -from resources import logging as init_logging -# Initialize Logger. -logger = init_logging.get_logger(__name__) +# Initialize logging. +# Since this is a library, we specifically only modify logging if the library is being run alone. +try: + # First, try to import the variable specific to our library logging. + from resources.logging import graph_library_logger + + # It worked, so we know the project is being run stand alone, probably as a unittest. + # Proceed to configure logging. + from resources.logging import get_logger as init_logging + logger = init_logging(__name__) +except ModuleNotFoundError: + # Above import failed. Project is being run as a library. + # Just import existing logger and do not modify. + import logging as init_logging + logger = init_logging.getLogger('graph_library') class Edge(basic_edge.Edge): diff --git a/resources/directed_graph/graph.py b/resources/directed_graph/graph.py index 97097eb..20753a8 100644 --- a/resources/directed_graph/graph.py +++ b/resources/directed_graph/graph.py @@ -16,11 +16,23 @@ import math import resources.basic_graph.graph as basic_graph import resources.directed_graph.edge as directed_edge import resources.directed_graph.node as directed_node -from resources import logging as init_logging -# Initialize Logger. -logger = init_logging.get_logger(__name__) +# Initialize logging. +# Since this is a library, we specifically only modify logging if the library is being run alone. +try: + # First, try to import the variable specific to our library logging. + from resources.logging import graph_library_logger + + # It worked, so we know the project is being run stand alone, probably as a unittest. + # Proceed to configure logging. + from resources.logging import get_logger as init_logging + logger = init_logging(__name__) +except ModuleNotFoundError: + # Above import failed. Project is being run as a library. + # Just import existing logger and do not modify. + import logging as init_logging + logger = init_logging.getLogger('graph_library') class Graph(basic_graph.Graph): diff --git a/resources/directed_graph/node.py b/resources/directed_graph/node.py index 634d49e..801c751 100644 --- a/resources/directed_graph/node.py +++ b/resources/directed_graph/node.py @@ -15,11 +15,23 @@ Essentially the "vertex" in a Graph data structure. # User Class Imports. import resources.basic_graph.node as basic_node import resources.directed_graph.edge as directed_edge -from resources import logging as init_logging -# Initialize Logger. -logger = init_logging.get_logger(__name__) +# Initialize logging. +# Since this is a library, we specifically only modify logging if the library is being run alone. +try: + # First, try to import the variable specific to our library logging. + from resources.logging import graph_library_logger + + # It worked, so we know the project is being run stand alone, probably as a unittest. + # Proceed to configure logging. + from resources.logging import get_logger as init_logging + logger = init_logging(__name__) +except ModuleNotFoundError: + # Above import failed. Project is being run as a library. + # Just import existing logger and do not modify. + import logging as init_logging + logger = init_logging.getLogger('graph_library') class Node(basic_node.Node): diff --git a/resources/state_machine/edge.py b/resources/state_machine/edge.py index 6a1fbdc..36a9310 100644 --- a/resources/state_machine/edge.py +++ b/resources/state_machine/edge.py @@ -14,11 +14,23 @@ Essentially the "node connection" in a Graph data structure. # User Class Imports. import resources.directed_graph.edge as directed_edge import resources.state_machine.node as sm_node -from resources import logging as init_logging -# Initialize Logger. -logger = init_logging.get_logger(__name__) +# Initialize logging. +# Since this is a library, we specifically only modify logging if the library is being run alone. +try: + # First, try to import the variable specific to our library logging. + from resources.logging import graph_library_logger + + # It worked, so we know the project is being run stand alone, probably as a unittest. + # Proceed to configure logging. + from resources.logging import get_logger as init_logging + logger = init_logging(__name__) +except ModuleNotFoundError: + # Above import failed. Project is being run as a library. + # Just import existing logger and do not modify. + import logging as init_logging + logger = init_logging.getLogger('graph_library') class Edge(directed_edge.Edge): diff --git a/resources/state_machine/graph.py b/resources/state_machine/graph.py index 499c889..fe5430f 100644 --- a/resources/state_machine/graph.py +++ b/resources/state_machine/graph.py @@ -10,17 +10,28 @@ Parent structure containing various Nodes and Edges. """ # System Imports. -import math # User Class Imports. import resources.directed_graph.graph as directed_graph import resources.state_machine.edge as sm_edge import resources.state_machine.node as sm_node -from resources import logging as init_logging -# Initialize Logger. -logger = init_logging.get_logger(__name__) +# Initialize logging. +# Since this is a library, we specifically only modify logging if the library is being run alone. +try: + # First, try to import the variable specific to our library logging. + from resources.logging import graph_library_logger + + # It worked, so we know the project is being run stand alone, probably as a unittest. + # Proceed to configure logging. + from resources.logging import get_logger as init_logging + logger = init_logging(__name__) +except ModuleNotFoundError: + # Above import failed. Project is being run as a library. + # Just import existing logger and do not modify. + import logging as init_logging + logger = init_logging.getLogger('graph_library') class Graph(directed_graph.Graph): diff --git a/resources/state_machine/node.py b/resources/state_machine/node.py index 965e837..3be00b6 100644 --- a/resources/state_machine/node.py +++ b/resources/state_machine/node.py @@ -14,11 +14,23 @@ Essentially the "vertex" in a Graph data structure. # User Class Imports. import resources.directed_graph.node as directed_node import resources.state_machine.edge as sm_edge -from resources import logging as init_logging -# Initialize Logger. -logger = init_logging.get_logger(__name__) +# Initialize logging. +# Since this is a library, we specifically only modify logging if the library is being run alone. +try: + # First, try to import the variable specific to our library logging. + from resources.logging import graph_library_logger + + # It worked, so we know the project is being run stand alone, probably as a unittest. + # Proceed to configure logging. + from resources.logging import get_logger as init_logging + logger = init_logging(__name__) +except ModuleNotFoundError: + # Above import failed. Project is being run as a library. + # Just import existing logger and do not modify. + import logging as init_logging + logger = init_logging.getLogger('graph_library') class Node(directed_node.Node): -- GitLab