Null safe support for Python

Overview

Null Safe Python

Null safe support for Python.

Installation

pip install nullsafe

Quick Start

Dummy Class

class Dummy:
    pass

Normal Python code:

o = Dummy()

try:
    value = o.inexistent
except AttributeError:
    print("oops")

With nullsafe:

from nullsafe import undefined, _

o = Dummy()

value = _(o).inexistent

if value is undefined:
    print("oops")

Note that if not value and if value == None also works.

Documentation

Basics

There are 5 values importable in nullsafe root:

class NullSafeProxy: (o: T)

Receives an object o on instantiation.

Proxy class for granting nullsafe abilities to an object.

class NullSafe: ()

No argument needed.

Nullish class with with nullsafe abilities. Instances will have a falsy boolean evaluation, equity comparison (==) to None and instance of NullSafe returns True, otherwise False. Identity comparison (is) to None will return False. It also has a __call__ method that always returns undefined.

variable undefined: NullSafe

Instance of Nullsafe, this instance will be returned for all nullish access in a proxied object, enabling identity comparison value is undefined for code clarity.

function nullsafe: (o: T) -> T | NullSafe | NullSafeProxy[T]

Receives an object o as argument.

Helper function that checks if object is nullish and return the proxied object.

return undefined if o is None or undefined, otherwise return the proxied object NullSafeProxy[T].

This function is generic typed ((o: T) -> T), code autocompletions and linters functionalities will remain. Disclaimer: If the object was not typed before proxy, it obviously won't come out typed out of the blue.

function _: (o: T) -> T | NullSafe | NullSafeProxy[T] (alias to nullsafe)

Alias to nullsafe, used for better code clarity.

Implementation

Nullsafe abilities are granted after proxying an object through NullSafeProxy. To proxy an object pass it through _() or nullsafe(). Due to language limitation, the implementation does not follow the "return the first nullish value in chain", instead it "extend undefined (custom nullish value) until the end of chain". Inexistent values of a proxied object and its subsequent values in chain will return undefined.

Import

from nullsafe import undefined, _

Usage

Various ways of using nullsafe.

The examples shown will be using the _ import instead of nullsafe for code clarity. For better understanding, the Javascript equivalents will be shown as comments.

Null safe attribute access

Proxied object doing a possibly AttributeError access.

o = Dummy()

# o.inexistent
assert _(o).inexistent is undefined
assert _(o).inexistent == None   # undefined == None
assert not _(o).inexistent       # bool(undefined) == False

# o.inexistent?.nested
assert _(o).inexistent.nested is undefined

# o.existent.inexistent?.nested
assert _(o.existent).inexistent.nested is undefined

# o.maybe?.inexistent?.nested
assert _(_(o).maybe).inexistent.nested is undefined

# o.inexistent?.inexistcall("anything").inexistent.nested().final
assert _(o).inexistent.inexistcall("anything").inexistent.nested().final is undefined

Null safe item access

Proxied object doing a possibly KeyError access.

o = Dummy() # dict works too !

# o.inexistent
assert _(o)["inexistent"] is undefined
assert _(o)["inexistent"] == None    # undefined == None
assert not _(o)["inexistent"]        # bool(undefined) == False

# o.inexistent?.nested
assert _(o)["inexistent"]["nested"] is undefined

# o.existent.inexistent?.nested
assert _(o["existent"])["inexistent"]["nested"] is undefined

# o.maybe?.inexistent?.nested
assert _(_(o)["maybe"])["inexistent"]["nested"] is undefined

# o.inexistent?.inexistcall("anything").inexistent.nested().final
assert _(o)["inexistent"]["inexistcall"]("anything")["inexistent"]["nested"]()["final"] is undefined

Null safe post evaluation

Possibly None or undefined object doing possibly AttributeError or KeyError access.

Note: This only works if the seeking value is accessible, see limitations

o = Dummy() # dict works too !
o.nay = None

# o.nay?.inexistent
assert _(o.nay).inexistent is undefined
assert _(o.nay).inexistent == None   # undefined == None
assert not _(o.nay).inexistent       # bool(undefined) == False

# o.nay?.inexistent.nested
assert _(o.nay).inexistent.nested is undefined

# o.nay?.inexistent().nested
assert _(o.nay).inexistent().nested is undefined
o = Dummy() # dict works too !
o["nay"] = None

# o.nay?.inexistent
assert _(o["nay"])["inexistent"] is undefined

# o.nay?.inexistent.nested
assert _(o["nay"])["inexistent"]["nested"] is undefined

# o.nay?.inexistent().nested
assert _(o["nay"])["inexistent"]()["nested"] is undefined

Combined usage

Of course you can combine different styles.

assert _(o).inexistent["inexistent"].inexistent.inexistent["inexistent"]["inexistent"] is undefined

Limitations

List of limitations that you may encounter.

undefined behavior

undefined is actually an instance of NullSafe, the actual mechanism used for nullsafe chaining, it cannot self rip the nullsafe functionality when the chain ends (because it doesn't know), so the following instruction is technically correct but probably not the wanted behavior.

val = _(o).inexistent

assert val.another_inexistent is undefined

Post evaluation

In other languages like Javascript, it checks for each item in the chain and return undefined on the first nullish value, which in fact is post-evaluated. This is not possible in python because it raises an AttributeError or KeyError on access attempt, unless it returns None (see one of the available usage), so it must proxy the instance that may contain the attr or key before accessing.

try:
    val = _(o.inexistent).nested # AttributeError: '
   
    ' object has no attribute 'inexistent'
   
except AttributeError:
    assert True
assert _(o).inexistent.nested is undefined

Contributing

Contributions welcomed ! Make sure it passes current tests tho.

You might also like...
You can easily send campaigns, e-marketing have actually account using cash will thank you for using our tools, and you can support our Vodafone Cash +201090788026

*** Welcome User Sorry I Mean Hello Brother ✓ Devolper and Design : Mokhtar Abdelkreem ========================================== You Can Follow Us O

Irrigation Component V4 providing support for a custom card
Irrigation Component V4 providing support for a custom card

Irrigation Component V4 This release sees the delivery of a custom card https://github.com/petergridge/irrigation_card to render the program options s

Library support get vocabulary from MEM

Features: Support scraping the courses in MEM to take the vocabulary Translate the words to your own language Get the IPA for the English course Insta

Kellogg bad | Union good | Support strike funds

KelloggBot Credit to SeanDaBlack for the basis of the script. req.py is selenium python bot. sc.js is a the base of the ios shortcut [COMING SOON] Set

Custom Weapons 3 attribute support for Custom Weapons X

CW3toX Allows use of Custom Weapons 3 attributes in Custom Weapons X. Requiremen

Wordler - A program to support you to solve the wordle puzzles

solve wordle (https://www.powerlanguage.co.uk/wordle) A program to support you t

HatAsm - a HatSploit native powerful assembler and disassembler that provides support for all common architectures

HatAsm - a HatSploit native powerful assembler and disassembler that provides support for all common architectures.

[x]it! support for working with todo and check list files in Sublime Text
[x]it! support for working with todo and check list files in Sublime Text

[x]it! for Sublime Text This Sublime Package provides syntax-highlighting, shortcuts, and auto-completions for [x]it! files. Features Syntax highlight

Todos os exercícios do Curso de Python, do canal Curso em Vídeo, resolvidos em Python, Javascript, Java, C++, C# e mais...
Todos os exercícios do Curso de Python, do canal Curso em Vídeo, resolvidos em Python, Javascript, Java, C++, C# e mais...

Exercícios - CeV Oferecido por Linguagens utilizadas atualmente O que vai encontrar aqui? 👀 Esse repositório é dedicado a armazenar todos os enunciad

Releases(v0.2.1)
Owner
Paaksing
Paaksing
A python module for DeSo

DeSo.py A python package for DeSo. Developed by ItsAditya Run pip install deso to install the module! Examples of How To Use DeSo.py Getting $DeSo pri

ItsAditya 0 Jun 30, 2022
This library is an abstraction for Splunk-related development, maintenance, or migration operations

This library is an abstraction for Splunk-related development, maintenance, or migration operations. It provides a single CLI or SDK to conveniently perform various operations such as managing a loca

NEXTPART 6 Dec 21, 2022
Intelligent Employer Profiling Platform.

Intelligent Employer Profiling Platform Setup Instructions Generating Model Data Ensure that Python 3.9+ and pip is installed. Install project depende

Harvey Donnelly 2 Jan 09, 2022
Easy, clean, reliable Python 2/3 compatibility

Overview: Easy, clean, reliable Python 2/3 compatibility python-future is the missing compatibility layer between Python 2 and Python 3. It allows you

Python Charmers 1.2k Jan 08, 2023
Project 2 for Microsoft Azure on WUT

azure-proj2 Project 2 for Microsoft Azure on WUT Table of contents Team Tematyka projektu Architektura Opis rozwiązania Demo dzałania The Team Krzyszt

1 Dec 07, 2021
Mdisk - 🚧 On Construction 🚧

Mdisk Install For Package pip install mdisk pip install git+https://github.com/HeimanPictures/Mdisk.git Usage You can use this as python module or via

AkKiL 6 Aug 08, 2022
FCurve-Cleaner: Tries to clean your dense mocap graphs like an animator would

Tries to clean your dense mocap graphs like an animator would! So it will produce a usable artist friendly result while maintaining the original graph.

wiSHFul97 5 Aug 17, 2022
Bring A Trailer(BAT) is a popular online auction website for enthusiast cars. This traverse auction results and saves them as CSV

BaT Data Grabber Bring A Trailer(BAT) is a popular online auction website for enthusiast cars. This traverse auction results and saves them as CSV Bri

Elliot Weil 2 Oct 31, 2021
Hashcrack: Hash Bruteforse tool using python

HashCrack Hash Bruteforse tool Usage hashcrack.py -n 6 -c lower -l 5 -a md5 -t 3

Lev 1 May 04, 2022
Custom Weapons 3 attribute support for Custom Weapons X

CW3toX Allows use of Custom Weapons 3 attributes in Custom Weapons X. Requiremen

2 Mar 01, 2022
Xoroshiro-cairo - A xoroshiro128** pseudorandom number generator implementation in Cairo

xoroshiro-cairo A xoroshiro128** pseudorandom number generator implementation in

Milan Cermak 26 Oct 05, 2022
Tutorials on advanced python topics, and literate programming framework to write them.

Advanced course on Python3 This course covers several topics Python decorators The python object system / meta classes Also see my text on Python impo

Michael Moser 59 Dec 19, 2022
Really bad lisp implementation. Fun with pattern matching.

Lisp-py This is a horrible, ugly interpreter for a trivial lisp. Don't use it. It was written as an excuse to mess around with the new pattern matchin

Erik Derohanian 1 Nov 23, 2021
An Advent calendar of small programming puzzles for a variety of skill sets and skill levels.

Advent of Code 2021 The Advent of Code is an Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be sol

Evan Cope 0 Feb 13, 2022
Unfinished Python library based on ndspy, for Zelda: Phantom Hourglass and Spirit Tracks.

zed An unfinished library and toolset by me, for viewing and editing files from The Legend of Zelda: Phantom Hourglass and The Legend of Zelda: Spirit

4 Oct 13, 2022
Chemical equation balancer

Chemical equation balancer Balance your chemical equations with ease! Installation $ git clone

Marijan Smetko 4 Nov 26, 2022
PyScaffold is a project generator for bootstrapping high quality Python packages

PyScaffold is a project generator for bootstrapping high quality Python packages, ready to be shared on PyPI and installable via pip. It is easy to use and encourages the adoption of the best tools a

PyScaffold 1.7k Jan 03, 2023
Euler 021 Py - Euler Problem 021 solved in Python

Euler_021_Py Euler Problem 021 solved in Python Let d(n) be defined as the sum o

Ariel Tynan 1 Jan 24, 2022
An OpenSource crowd-sourced cooking recipes website

An OpenSource crowd-sourced cooking recipes website

21 Jul 31, 2022
A Notifier Program that Notifies you to relax your eyes Every 15 Minutes👀

Every 15 Minutes is an application that is used to Notify you to Relax your eyes Every 15 Minutes, This is fully made with Python and also with the us

FSP Gang s' YT 2 Nov 11, 2021