Skip to main content

Allow creation of circular module dependencies between classes

Project description

Cyclic Classes

Python package PyPI Code style: black pylint NoPrint

About

Ever had a situation when you wanted to create a cyclic reference between two objects, but don't want to maintain a large singular file? You're tired of seeing "cyclic-import" errors? This package is for you! Simply "register" a class you want to share between different modules and you're pretty much good to go!

See the documentation for more information.

Requirements

There's NONE!

Installation

Pull straight from this repo to install manually or just use pip: pip install cyclic-classes will do the trick.

Usage

Consider a package myk8s with two modules, maybe one is to reference a k8s deployment and the other one is for pods within that deployment.

deployment.py

from .pod import Pod

class Deployment:
    def __init__(self, name: str):
        self.name = name
    
    @property
    def pods(self):
        return [Pod(f"{self.name}-pod-{i}") for i in range(3)]

Now, if you want to create a back-reference for Deployment within Pod, like this: pod.py

from .deployment import Deployment

class Pod:
    def __init__(self, name: str):
        self.name = name
        
    @property
    def deployment(self):
        return Deployment(self.name.split("-")[0])

In the above example, you would get a cyclic-import error. To avoid this, you can use cyclic_classes to register the classes you want to share between modules. Do so like this:

deployment.py

from cyclic_classes import register, cyclic_import

with cyclic_import():  # This is required to avoid cyclic-import errors - you're actually importing a registered class underneath, but IDE will think it's your actual class
    from .pod import Pod

@register  # You have to register the class you want to access so that Pod will also be able to use it in the pod.py file
class Deployment:
    def __init__(self, name: str):
        self.name = name
    
    @property
    def pods(self):
        return [Pod(f"{self.name}-pod-{i}") for i in range(3)]

Now, if you want to create a back-reference for Deployment within Pod, like this: pod.py

from cyclic_classes import register, cyclic_import

with cyclic_import():
    from .deployment import Deployment

@register  # Making Pod available to cyclic_import
class Pod:
    def __init__(self, name: str):
        self.name = name
        
    @property
    def deployment(self):
        return Deployment(self.name.split("-")[0])

And that's it! You can now use the classes in your code without any issues.

Note

Cyclic import supports multiple ways of imports, including relative imports, absolute imports, and even module imports. As such, in the cyclic_import context you can use either of the following:

import myk8s.deployment as depl  # And later use depl.Deployment
from .deployment import Deployment
from myk8s.deployment import Deployment

# Not recommended, but also possible
# Reason: Such imports wouldn't work even if there was no cyclic import issue, but it works with cyclic import (you'll get a warning though) and some IDEs think it's correct 
from deployment import Deployment
import deployment

This also works with aliases! So feel free to use import ... as ... or from ... import ... as ... as you wish.

Development

Installation

Install virtual environment and cyclic_classes package in editable mode with dev dependencies.

python -m venv venv
source venv/bin/activate
pip install -e .[dev]

How to?

Automate as much as we can, see configuration in pyproject.toml file to see what are the flags used.

staging format  # Reformat the code
staging lint    # Check for linting issues
staging test    # Run unit tests and coverage report

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cyclic_classes-0.0.2.tar.gz (12.8 kB view details)

Uploaded Source

Built Distribution

cyclic_classes-0.0.2-py3-none-any.whl (11.8 kB view details)

Uploaded Python 3

File details

Details for the file cyclic_classes-0.0.2.tar.gz.

File metadata

  • Download URL: cyclic_classes-0.0.2.tar.gz
  • Upload date:
  • Size: 12.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for cyclic_classes-0.0.2.tar.gz
Algorithm Hash digest
SHA256 2deca6520172fff9fd94dd2335395ae437523d5bfd72bc533091e2937e586a6b
MD5 63cbf3cfca07fed87d311a8ece87dce4
BLAKE2b-256 e26889459fe522a06849429032bf849c9c078a9d7023d40c942ecf650aa9d290

See more details on using hashes here.

File details

Details for the file cyclic_classes-0.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for cyclic_classes-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b05c8cf62107e884b15d751c6129f5f74ddbd5b52aedb05d5278860cdc4bd324
MD5 9a4d147f2392e5c3e310d9d5ac0d60e8
BLAKE2b-256 b3b203ec5ab42a5ce25211cb8d9222d90eb7b1a4ed4d887b4843da62d134578a

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page