Skip to main content

This is a Python library based on calling of frame's stack at runtime and mainly implements some C# features.

Project description

pymagic9

license Tests codecov

This is a Python library based on calling the stack of frames at runtime and analyzing the code object of frames. Basically, it implements some C# features. For example, it contains the nameof function and auto-implemented properties. See the documentation for more information.

Installation

You can install pymagic9 using pip:

pip install pymagic9

Features

getframe: The sys._getframe function is used here if it exists in the version of python being used. Otherwise, the _getframe polyfill is used.

isemptyfunction: Checks if a function is empty or not.

isfunctionincallchain: Determines whether the given function object or code object is present in the call chain.

nameof: This function correctly determines the "name" of an object, without being tied to the object itself. It can be used to retrieve the name of variables, functions, classes, modules, and more.

PropertyMeta: This metaclass allows you to create auto-implemented properties (like in C#, where you can declare properties without explicitly defining a getter and setter), for which you can use an ellipsis or empty functions to indicate that the Python itself would create the auto-implemented accessor.

Usage of auto-implemented properties

  1. Import the PropertyMeta metaclass and assign it as a metaclass for the desired class:
from pymagic9 import PropertyMeta


class Person(metaclass=PropertyMeta):
    pass
  1. Create properties in this class with empty accessors (using empty function or ellipsis) to indicate that this property will be auto-implemented:
from pymagic9 import PropertyMeta


class Person(metaclass=PropertyMeta):
    """class Person"""
    def __init__(self, name):
        self.name = name

    name = property(fget=...,)           # readonly property
    age = property(fget=..., fset=...,)  # ordinary property
  1. Now for an ordinary property we can get and put values into it at any time. But for a readonly property, you can put a value into it only once, at the time of creating an instance of the class:
from pymagic9 import PropertyMeta


class Person(metaclass=PropertyMeta):
    """class Person"""
    def __init__(self, name):
        self.name = name
        # self.name = "Sam"  # raise AttributeError: 'property' is readonly (reassigning value)

    name = property(fget=...,)           # readonly property
    age = property(fget=..., fset=...,)  # ordinary property

    
if __name__ == "__main__":
    person = Person("Tom")
    person.age = 24
    print(person.name + ',', person.age)  # Tom, 24
    # person.name = "Sam"  # raise AttributeError: 'property' is readonly
  1. To delete a property value, use the del operator:
from pymagic9 import PropertyMeta


class Person(metaclass=PropertyMeta):
    """class Person"""
    def __init__(self, name):
        self.name = name

    name = property(fget=...,)           # readonly property
    age = property(fget=..., fset=...,)  # ordinary property

    
if __name__ == "__main__":
    person = Person("Tom")
    person.age = 24
    print(person.name + ',', person.age)  # Tom, 24
    del person.name
    # print(person.name)  # raise AttributeError: auto-implemented field does not exist or has already been erased
  1. If the getter is specified by an empty accessor (using empty function or ellipsis), and the setter is not an empty function, then setter will also be called. This can be used as a callback when assigning a value to a property:
from pymagic9 import nameof, PropertyMeta


def NotifyPropertyChanged(propertyname, value):
    """Notify property changed"""
    # Do something
    print(propertyname + ',', value)


class Person(metaclass=PropertyMeta):
    """class Person"""
    def __init__(self, name):
        self.name = name

    name = property(fget=...,)           # readonly property
    age = property(fget=..., fset=...,)  # ordinary property
    
    @property
    def height(self):
        """Person height in cm"""
        return
    
    @height.setter
    def height(self, value):
        NotifyPropertyChanged(nameof(self.height), value)


if __name__ == "__main__":
    person = Person("Tom")
    person.age = 24
    print(person.name + ',', person.age)  # Tom, 24
    person.height = 180  # height, 180
  1. Similar code for Python 2.7 looks like this:
from pymagic9 import nameof, PropertyMeta

__metaclass__ = PropertyMeta


def NotifyPropertyChanged(propertyname, value):
    """Notify property changed"""
    # Do something
    print(propertyname + ', ' + str(value))
    
    
class Person:
    """class Person"""
    def __init__(self, name):
        self.name = name

    name = property(fget=Ellipsis,)                # readonly property
    age = property(fget=Ellipsis, fset=Ellipsis,)  # ordinary property
    
    @property
    def height(self):
        """Person height in cm"""
        return
    
    @height.setter
    def height(self, value):
        NotifyPropertyChanged(nameof(self.height), value)


if __name__ == "__main__":
    person = Person("Tom")
    person.age = 24
    print(person.name + ', ' + str(person.age))  # Tom, 24
    person.height = 180  # height, 180

The detailed operating principle is described in the documentation.

Compatibility

pymagic9 is compatible with the following versions of Python:

  • CPython 2.7
  • CPython 3.6
  • CPython 3.7
  • CPython 3.8
  • CPython 3.9
  • CPython 3.10

It is supported on Windows, Ubuntu, and MacOS platforms.

Documentation

For more information and detailed usage examples, please refer to the documentation.

License

This project is licensed under the Apache License 2.0. See the LICENSE file for more details.

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

pymagic9-0.9.0.tar.gz (17.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pymagic9-0.9.0-py2.py3-none-any.whl (15.4 kB view details)

Uploaded Python 2Python 3

File details

Details for the file pymagic9-0.9.0.tar.gz.

File metadata

  • Download URL: pymagic9-0.9.0.tar.gz
  • Upload date:
  • Size: 17.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.7.8

File hashes

Hashes for pymagic9-0.9.0.tar.gz
Algorithm Hash digest
SHA256 d6e382c2f4083458d134636f911fbd9bc980f537f5caedf24dadc237e3696b48
MD5 8976a8bc011adc3995a53993e0541068
BLAKE2b-256 9b19614a7a412bd438063f39206640b7471455b53f2f8c1a4aff88a40ad34216

See more details on using hashes here.

File details

Details for the file pymagic9-0.9.0-py2.py3-none-any.whl.

File metadata

  • Download URL: pymagic9-0.9.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 15.4 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.7.8

File hashes

Hashes for pymagic9-0.9.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 2aba7f4d686a6f114cc3e7efec5719482aefc069faf1efdd9c8084f360644d32
MD5 4669e5177d5aa517c51c06850d4ad49a
BLAKE2b-256 3ce07933525d8f9054165ab250c49465017153c53cfaacf0910507f6344f07bb

See more details on using hashes here.

Supported by

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