Package: globality-black
Globality blackDISCLAIMERTech talkA wrapper forblack, adding pre- and post-processing
to better align with Globality conventions.globality-blackperforms the following steps:pre-processing: to protect from black actionsblackpostprocessing: to revert / correct black actionsNote: if you are not familiar with black (or need a refresh), please
read ourBlack refresh.Table of contentsGlobality blackTable of contentsInstallationUsageCLIPycharmJupyterLabVScodeWorking with remotesShortcutsWorking with notebooksFeaturesBlank linesDotted chainsLength one tuplesComprehensionsBefore globality-blackAfter globality-blackPartially disable globality-blackPending / Future workBlack refreshMagic commaFAQTestsContributingSubmit and issueSubmit a pull requestCode of ConductInstallationpip install globality-blackUsageThere are two ways to useglobality-black, via CLI, or importing the helpers in the library.
Next, we show some typical use cases:CLIPlease see command line arguments runningglobality-black --help.PycharmTo useglobality-blackin PyCharm, go to PyCharm -> Preferences... -> Tools -> External Tools -> Click + symbol
to add new external tool.Recommended configuration to format the current file:Program: path toglobality-black, e.g./Users/marty-mcfly/miniconda3/envs/gb/bin/globality-blackArguments:$FilePath$Working directory:$ProjectFileDir$Recommended configuration to check the whole repo (but not formatting it it):Program: path toglobality-black, e.g./Users/marty-mcfly/miniconda3/envs/gb/bin/globality-blackArguments:. --checkWorking directory:$ProjectFileDir$Next, configure a keymap, as inhere.JupyterLabWe can leveragethisextension,
with a custom formatter. Here we explain how to get the following options:There are two ways to applyglobality-black, see left-hand-side, or by clicking on the button next to "Code". We will configure
the extension to make it apply theisort + globality-blackpipeline when clicking such button.To do so, install the extension, generate the config for jupyter lab and edit it:pipinstalljupyterlab_code_formatter
jupyterlab--generate-config
vim~/.jupyter/jupyter_lab_config.pyYou might already have some config injupyter_lab_config. If so, you might want to omit
the second command above, and edit it (vim) instead.In any case, we will add the following code:fromjupyterlab_code_formatter.formattersimportSERVER_FORMATTERSfromglobality_black.jupyter_formatterimportGlobalityBlackFormatterSERVER_FORMATTERS['globality-black']=GlobalityBlackFormatter(line_length=100)Then, go to the extension preferences, and add:{"preferences":{"default_formatter":{"python":["isort","globality-black",],}},"isort":{"combine_as_imports":true,"force_grid_wrap":4,"force_to_top":"true","include_trailing_comma":true,"known_third_party":["wandb","tqdm"],"line_length":100,"lines_after_imports":2,"multi_line_output":3,}}Notes:The last step above translates into user settings saved in~/.jupyter/lab/user-settings/@ryantam626/.The extension is applied to all cells in the notebook. It can be configured to be applied just to
the current cell, if interested.The extension is applied to each cell in isolation. Hence, if multiple imports appear in different
cells, they won't be merged together on top of the notebook.VScodeTo useglobality-blackin VScode, install the extensionExternal formatters.Then, go to Preferences: Settings (JSON). A filesettings.jsonwill open. Add this to the file:"[python]":{"editor.codeActionsOnSave":{"source.organizeImports":true},"editor.defaultFormatter":"SteefH.external-formatters",},"isort.args":["--profile","black"],This will configure isort to run when saving, and glo-black as the default
formatter. Add also this["externalFormatters.languages":{"python":{"command":"$PATH_TO_ENV/bin/globality-black","arguments":["-",]}},"isort.interpreter":["$PATH_TO_ENV/bin/python"],]setting or replacing$PATH_TO_ENVwith whatever you need to get to theglobality-blackPython env.Working with remotesImportant: these two paths have to be absolute paths, and need to be the
same everywhere you use VScode. This means that if you use VScode on remotes (e.g. an EC2 instance),
the same paths needs to exist. Obviosuly, that's not possible, since e.g.
in EC2 you'll have/home/ubuntu/...and in your machine/Users/john/.... A workaround for this is to create a symbolic link in your instance, e.g:sudoln-s/home/ubuntu/Users/johnShortcutsTo configure shortcuts, go toPreferences: Keyboard Shortcuts (JSON)from the Palette (command+shift+p). The filekeybindings.jsonwill open.
Add to this file:[{"key":"cmd+shift+j","command":"editor.action.formatDocument","when":"editorHasDocumentFormattingProvider && editorTextFocus && !editorReadonly && !inCompositeEditor"}]This will allow you to runglobality-blackon the currently open file,
passing the content of the file via stdin.Working with notebooksTo format notebooks, there is a shortcut{"key":"shift+alt+f","command":"notebook.formatCell","when":"editorHasDocumentFormattingProvider && editorTextFocus && inCompositeEditor && notebookEditable && !editorReadonly && activeEditor == 'workbench.editor.notebook'",}that you can modify if you don't like this combination. This will format the
current cell with the default formatter. I did not find a way to run isort
though. There is a "format notebook on save" option, but it's not exactly what
we configured for python files. That would run isort + glo-black.FeaturesBlank linesBlack would remove those blank lines afterwandbandscikit-learnbelow:graph.use(
    "wandb",

    "scikit-learn",

    # we love pandas
    "pandas",
)globality-blackprotects those assuming the developer added them for readability.Dotted chainsIn a similar fashion to the "blank lines" feature, "dotted chains" allows to keep the block:return(df_field[COLUMNS_PER_FIELD[name]].dropna(subset=["column"]).reset_index(drop=True).assign(mapped_type=MAP_DICT[name]))LABELS=set(df[df.labels.apply(len)>0].flag.apply(curate).apply(normalize).unique())the same. In this feature,we don't explode anythingbut rather protect code assuming it was
written by this in purpose for readability.Length one tuplesThis is a very simple and specific feature. Black (at least up to 21.9b0) has a bug so that tuples
with one element are compressed as inx=(3,)becomesx=(3,)Seehttps://github.com/psf/black/issues/1139#issuecomment-951014094. With globality-black,
will protect these.ComprehensionsExplode comprehensionsall dict comprehensionsany comprehension with an ifany comprehension with multiple for loops (see examples below)list / set comprehensions where the element:has a ternary operator (see examples below)has another comprehensionFor everything else, we rely onblack. Examples:Before globality-black[3 for _ in range(10)]

[3 for i in range(10) if i < 4]

{"a": 3 for _ in range(4)}

{"a": 3 for _ in range(4) if i < 4}

["odd" if i %% 2 == 0 else "even" for _ in range(10)]

double_comp1 = [3*i*j for i in range(10) for j in range(4)]

double_comp2 = [[i for i in range(7) if i < 5] for j in range(10)]

double_comp3 = {i: [i for i in range(7) if i < 5] for j in range(10) if i < 2}After globality-black[3 for _ in range(10)]

[
    3
    for i in range(10)
    if i < 4
]

{
    "a": 3
    for _ in range(4)
}

{
    "a": 3
    for _ in range(4)
    if i < 4
}

[
    "odd" if i %% 2 == 0 else "even"
    for _ in range(10)
]

double_comp1 = [
    3 * i * j
    for i in range(10)
    for j in range(4)
]

double_comp2 = [
    [i for i in range(7) if i < 5]
    for j in range(10)
]

double_comp3 = {
    i: [i for i in range(7) if i < 5]
    for j in range(10)
    if i < 2
}Note that in the last two comprehensions, the nested comprehensions are not exploded even though
having an if. This is a limitation ofglobality-black, but we believe not very frequent
in everyday cases. If you really want to explode those and makeglobality-blackrespect it,
please use the feature explained next.Partially disable globality-blackIf you see some block where you don't want to applyglobality-black, wrap it
with# fmt.offand# fmt:onand it will be ignored. Note that this is the same syntax as
forblack. For example, for readability you might want to do something as:# fmt: off
files_to_read = [
    (f"{key1}_{key2}", key1, key2, key1 + key2)
    for key1 in range(10)
]
# fmt: onNote that as a default (same asblack),globality-blackwill write the expression above as a
one-liner.Pending / Future workExplode ternary operators under some criteriaNested comprehensionsMagic comma for single element subscripts, due tothisPlease give us feedback if you find any issues, and checkknown_failedBlack refreshblackis an opinionated Python formatter that tries to save as much vertical space as possible. In
this regard, it compresses lines to the maximum character length that has been configured.black's
default is 88, whereas inglobality-blackwe use a default of 100 characters, as agreed for
Globality repos globally. If you want to have a custom max character length, add apyproject.tomlfile to the root of your repo. This works the same way as inblack, andglobality-blackwill
take your config from there.See howblackworks in theirREADME. It is especially useful to
reviewthis section, where
important recent features are explained.Magic commablackadded a feature at the end of 2020 that we used to call the "magic comma". It's one of the
first examples whereblackis giving a bit of freedom to the developer on how the final code will
look like (apart fromfmt:offandfmt:onto ignoreblackentirely). Read more about ithere.FAQHere we list a number of questions and solutions raised when presenting this project to other teams:I like this project, but this would destroy all our git history and git blamesOur recommendation is:Create a big PR for all your repo, and do the effort of reviewing the changes just once.Add a.git-blame-ignore-revsfile to your repo, ignoring the bulk commit whereglobality-blackis applied. Seeherefor more details.I like most of the changes, but in some places I really prefer the way I write the codeNo problem, for those specific cases where you like more your style, just wrap the block withfmt:offandfmt:on, see thePartially disable Globality Blacksection.100 characters per line is too short / too long for meJust add apyproject.tomlto the root of your repo (as the one in this very own
project) and specify your preferred length, see theBlack refreshsection.I want to know what will be changed before applying the changesPlease use the--diffoption from the CLI, see theCLIsection.I want to explode list of arguments, butglobality-blackis compressing them into one linePlease use the magic comma feature, seeMagic comma.TestsRun the tests as inbash entrypoint.sh testor simplypytest .Some options:-sto show prints and be able to debug--pdbto trigger debugger when having an exceptionpytest route_to_testto test a specific test filepytest route_to_test::test_functionto test a specific test functionpytest route_to_test::test_function[test_case]--cov-report termto show coverageYou might find other code inspectors inentrypoint.sh. Note that these are run
against your code if opening a pull request.ContributingAll contributions, bug reports, security issues, bug fixes, documentation improvements, enhancements, and ideas are welcome. This section is adapted and simplified
frompandas contribution guide.Submit and issueBug reports, security issues, and enhancement requests are an important part of making open-source software more stable and are curated through Github issues. When reporting and issue or request, please fill out the issue form fully to ensure others and the core development team can fully understand the scope of the issue.The issue will then show up to the community and be open to comments/ideas from others.Submit a pull requestdeboileris hosted on GitHub, and to contribute, you will need to sign up for a free GitHub account. We use Git for version control to allow many people to work together on the project. If you are new to Git, you can reference some of the resources in the pandas contribution guide cited above.Also, the project follows a standard forking workflow whereby contributors fork the repository, make changes, create a feature branch, push changes, and then create a pull request. To avoid redundancy, please follow all the instructions in the pandas contribution guide  cited above.Code of ConductAs contributors and maintainers to this project, you are expected to abide by the code of conduct. More information can be found at theContributor Code of Conduct.===============
Globality blackv0.1.0TODO