diff --git a/.gitignore b/.gitignore index b6fc905..c15047d 100644 --- a/.gitignore +++ b/.gitignore @@ -89,6 +89,8 @@ venv/ ENV/ env.bak/ venv.bak/ +newenv/* +newenv/ # Spyder project settings .spyderproject diff --git a/.pylintrc b/.pylintrc index 790cf5c..fac4492 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,565 +1,116 @@ -[MASTER] +[MAIN] +# Initialize Python path +init-hook= + import sys; sys.path.append('.') -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. -extension-pkg-whitelist= +# Enable Django plugin for proper Django support +load-plugins=pylint_django -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the blacklist. The -# regex matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. +# Use multiple processes (0 = auto-detect) jobs=1 -# Control the amount of potential inferred values when inferring a single -# object. This can help the performance when dealing with large functions or -# complex, nested conditions. -limit-inference-results=100 - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - -# Pickle collected data for later comparisons. +# Persistent data storage for comparisons persistent=yes -# Specify a configuration file. -#rcfile= - -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. +# Show helpful suggestions suggestion-mode=yes -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - [MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once). You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable=print-statement, - parameter-unpacking, - unpacking-in-except, - old-raise-syntax, - backtick, - long-suffix, - old-ne-operator, - old-octal-literal, - import-star-module-level, - non-ascii-bytes-literal, - raw-checker-failed, - bad-inline-option, - locally-disabled, - file-ignored, - suppressed-message, - useless-suppression, - deprecated-pragma, - use-symbolic-message-instead, - apply-builtin, - basestring-builtin, - buffer-builtin, - cmp-builtin, - coerce-builtin, - execfile-builtin, - file-builtin, - long-builtin, - raw_input-builtin, - reduce-builtin, - standarderror-builtin, - unicode-builtin, - xrange-builtin, - coerce-method, - delslice-method, - getslice-method, - setslice-method, - no-absolute-import, - old-division, - dict-iter-method, - dict-view-method, - next-method-called, - metaclass-assignment, - indexing-exception, - raising-string, - reload-builtin, - oct-method, - hex-method, - nonzero-method, - cmp-method, - input-builtin, - round-builtin, - intern-builtin, - unichr-builtin, - map-builtin-not-iterating, - zip-builtin-not-iterating, - range-builtin-not-iterating, - filter-builtin-not-iterating, - using-cmp-argument, - eq-without-hash, - div-method, - idiv-method, - rdiv-method, - exception-message-attribute, - invalid-str-codec, - sys-max-int, - bad-python3-import, - deprecated-string-function, - deprecated-str-translate-call, - deprecated-itertools-function, - deprecated-types-field, - next-method-defined, - dict-items-not-iterating, - dict-keys-not-iterating, - dict-values-not-iterating, - deprecated-operator-function, - deprecated-urllib-function, - xreadlines-attribute, - deprecated-sys-function, - exception-escape, - comprehension-escape - too-many-ancestors - line-too-long - arguments-differ - invalid-name - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable=c-extension-no-member - +# Disabled checks (modern Python 3 compatible list) +disable= + # Python 3 style checks + super-with-arguments, + + # General checks + too-many-ancestors, + line-too-long, + arguments-differ, + invalid-name, + duplicate-code, + + # Django specific + django-not-configured, + + # Formatting + trailing-whitespace, + bad-whitespace + +# Enabled checks +enable= + c-extension-no-member, + consider-using-f-string, + use-dict-literal, + consider-using-set-comprehension [REPORTS] - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. output-format=text - -# Tells whether to display a full report or only the messages. reports=no - -# Activate the evaluation score. score=yes - [REFACTORING] - -# Maximum number of nested blocks for function / method body max-nested-blocks=5 - -# Complete name of functions that never returns. When checking for -# inconsistent-return-statements if a never returning function is called then -# it will be considered as an explicit return statement and no message will be -# printed. -never-returning-functions=sys.exit - +never-returning-functions=sys.exit, os._exit [BASIC] - -# Naming style matching correct argument names. -argument-naming-style=snake_case - -# Regular expression matching correct argument names. Overrides argument- -# naming-style. -#argument-rgx= - -# Naming style matching correct attribute names. -attr-naming-style=snake_case - -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. -#attr-rgx= - -# Bad variable names which should always be refused, separated by a comma. -bad-names=foo, - bar, - baz, - toto, - tutu, - tata - -# Naming style matching correct class attribute names. -class-attribute-naming-style=any - -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. -#class-attribute-rgx= - -# Naming style matching correct class names. -class-naming-style=PascalCase - -# Regular expression matching correct class names. Overrides class-naming- -# style. -#class-rgx= - -# Naming style matching correct constant names. -# const-naming-style=UPPER_CASE - -# Regular expression matching correct constant names. Overrides const-naming- -# style. -#const-rgx= - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Naming style matching correct function names. +# Naming conventions +variable-naming-style=snake_case function-naming-style=snake_case - -# Regular expression matching correct function names. Overrides function- -# naming-style. -#function-rgx= - -# Good variable names which should always be accepted, separated by a comma. -good-names=i, - j, - k, - ex, - Run, - _ - -# Include a hint for the correct naming format with invalid-name. -include-naming-hint=no - -# Naming style matching correct inline iteration names. -inlinevar-naming-style=any - -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. -#inlinevar-rgx= - -# Naming style matching correct method names. method-naming-style=snake_case - -# Regular expression matching correct method names. Overrides method-naming- -# style. -#method-rgx= - -# Naming style matching correct module names. +class-naming-style=PascalCase module-naming-style=snake_case -# Regular expression matching correct module names. Overrides module-naming- -# style. -#module-rgx= - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -# These decorators are taken in consideration only for invalid-name. -property-classes=abc.abstractproperty - -# Naming style matching correct variable names. -variable-naming-style=snake_case - -# Regular expression matching correct variable names. Overrides variable- -# naming-style. -#variable-rgx= - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - -# Minimum lines number of a similarity. -min-similarity-lines=4 - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid defining new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_, - _cb - -# A regular expression matching the name of dummy variables (i.e. expected to -# not be used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore. -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io - - -[LOGGING] - -# Format style used to check logging format string. `old` means using % -# formatting, while `new` is for `{}` formatting. -logging-format-style=old - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules=logging - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# Tells whether to warn about missing members when the owner of the attribute -# is inferred to be None. -ignore-none=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - - -[SPELLING] - -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions=4 - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package.. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME, - XXX, - TODO - +# Name exceptions +bad-names=foo,bar,baz,toto,tutu,tata +good-names=i,j,k,ex,Run,_ [FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. max-line-length=100 - -# Maximum number of lines in a module. -max-module-lines=1000 - -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma, - dict-separator - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict, - _fields, - _replace, - _source, - _make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=cls - +indent-string=' ' +ignore-long-lines=^\s*(# )??$ [IMPORTS] - -# Allow wildcard imports from modules that define __all__. allow-wildcard-with-all=no +known-third-party=django,requests -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules=optparse,tkinter.tix - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled). -ext-import-graph= - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled). -import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled). -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - +[CLASSES] +defining-attr-methods=__init__,__new__,setUp,setUpTestData +exclude-protected=_asdict,_fields,_replace,_source,_make [DESIGN] - -# Maximum number of arguments for function / method. max-args=5 - -# Maximum number of attributes for a class (see R0902). max-attributes=7 - -# Maximum number of boolean expressions in an if statement. -max-bool-expr=5 - -# Maximum number of branch for function / method body. max-branches=12 - -# Maximum number of locals for function / method body. max-locals=15 - -# Maximum number of parents for a class (see R0901). max-parents=7 - -# Maximum number of public methods for a class (see R0904). max-public-methods=20 - -# Maximum number of return / yield for function / method body. +min-public-methods=2 max-returns=6 - -# Maximum number of statements in function / method body. max-statements=50 -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 +[TYPECHECK] +ignore-mixin-members=yes +ignore-none=yes +missing-member-hint=yes + +[PYTHON] +# Python 3 compatibility +python-version=3.7 +[DIALECT] +# Modern Python features +enable-rgx= + consider-using-f-string, + consider-using-namedtuple, + consider-using-set-comprehension, + use-dict-literal -[EXCEPTIONS] +[LOGGING] +logging-format-style=new -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception". -overgeneral-exceptions=Exception +[SIMILARITIES] +ignore-comments=yes +ignore-docstrings=yes +min-similarity-lines=4 + +[MISCELLANEOUS] +notes=FIXME,XXX,TODO diff --git a/.pylintrc_old b/.pylintrc_old new file mode 100644 index 0000000..790cf5c --- /dev/null +++ b/.pylintrc_old @@ -0,0 +1,565 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-whitelist= + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use. +jobs=1 + +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Specify a configuration file. +#rcfile= + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=print-statement, + parameter-unpacking, + unpacking-in-except, + old-raise-syntax, + backtick, + long-suffix, + old-ne-operator, + old-octal-literal, + import-star-module-level, + non-ascii-bytes-literal, + raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-symbolic-message-instead, + apply-builtin, + basestring-builtin, + buffer-builtin, + cmp-builtin, + coerce-builtin, + execfile-builtin, + file-builtin, + long-builtin, + raw_input-builtin, + reduce-builtin, + standarderror-builtin, + unicode-builtin, + xrange-builtin, + coerce-method, + delslice-method, + getslice-method, + setslice-method, + no-absolute-import, + old-division, + dict-iter-method, + dict-view-method, + next-method-called, + metaclass-assignment, + indexing-exception, + raising-string, + reload-builtin, + oct-method, + hex-method, + nonzero-method, + cmp-method, + input-builtin, + round-builtin, + intern-builtin, + unichr-builtin, + map-builtin-not-iterating, + zip-builtin-not-iterating, + range-builtin-not-iterating, + filter-builtin-not-iterating, + using-cmp-argument, + eq-without-hash, + div-method, + idiv-method, + rdiv-method, + exception-message-attribute, + invalid-str-codec, + sys-max-int, + bad-python3-import, + deprecated-string-function, + deprecated-str-translate-call, + deprecated-itertools-function, + deprecated-types-field, + next-method-defined, + dict-items-not-iterating, + dict-keys-not-iterating, + dict-values-not-iterating, + deprecated-operator-function, + deprecated-urllib-function, + xreadlines-attribute, + deprecated-sys-function, + exception-escape, + comprehension-escape + too-many-ancestors + line-too-long + arguments-differ + invalid-name + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages. +reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit + + +[BASIC] + +# Naming style matching correct argument names. +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style. +#argument-rgx= + +# Naming style matching correct attribute names. +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. +#class-attribute-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. +#class-rgx= + +# Naming style matching correct constant names. +# const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=i, + j, + k, + ex, + Run, + _ + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=no + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. +#variable-rgx= + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore. +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io + + +[LOGGING] + +# Format style used to check logging format string. `old` means using % +# formatting, while `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package.. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma, + dict-separator + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=cls + + +[IMPORTS] + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules=optparse,tkinter.tix + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled). +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled). +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + + +[DESIGN] + +# Maximum number of arguments for function / method. +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement. +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception". +overgeneral-exceptions=Exception diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index bb21ded..9e399e5 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -1,148 +1,83 @@ -# Use the latest stable version of Semaphore 2.0 YML syntax: version: v1.0 - -# Name your pipeline. In case you connect multiple pipelines with promotions, -# the name will help you differentiate between, for example, a CI build phase -# and delivery phases. name: Semaphore Python / Django Example Pipeline - -# An agent defines the environment in which your code runs. -# It is a combination of one of available machine types and operating -# system images. -# See https://docs.semaphoreci.com/article/20-machine-types -# and https://docs.semaphoreci.com/article/32-ubuntu-1804-image agent: machine: type: e1-standard-2 os_image: ubuntu2004 - global_job_config: prologue: commands: - sem-version python 3.8 - -# Blocks are the heart of a pipeline and are executed sequentially. -# Each block has a task that defines one or more jobs. Jobs define the -# commands to execute. -# See https://docs.semaphoreci.com/article/62-concepts blocks: - - name: "Install Dependencies" + - name: Install Dependencies task: - # This block installs all the python dependencies, - # as well as all the required Linux packages. - # The prologue section is always executed before each job on - # the block. - # See https://docs.semaphoreci.com/article/50-pipeline-yaml#prologue prologue: commands: - # Set the python version. - # See https://docs.semaphoreci.com/article/132-sem-service-managing-databases-and-services-on-linux - # Install Linux dependencies. - - sudo apt-get update && sudo apt-get install -y python3-dev && sudo apt-get install default-libmysqlclient-dev + - sudo apt-get update && sudo apt-get install -y python3-dev default-libmysqlclient-dev build-essential pkg-config libssl-dev + - python3 -m pip install --upgrade pip setuptools wheel jobs: - name: pip commands: - # Get the latest version of our source code from GitHub: - # See https://docs.semaphoreci.com/article/54-toolbox-reference#checkout - checkout - # Restore dependencies from cache. This command will not fail in - # case of a cache miss. In case of a cache hit, pip can use it - # to speed up the installation. - # For more info on caching, see https://docs.semaphoreci.com/article/149-caching - cache restore - # Install python dependencies. - # If not found in the cache, pip will download them. - pip download --cache-dir .pip_cache -r requirements.txt - # Persist downloaded packages for future jobs. - cache store - - - name: "Run Code Analysis" + env_vars: + - name: DJANGO_TEST_ENV + value: 'true' + - name: Run Code Analysis task: - # This block executes code analysis tests with pylint. prologue: commands: - checkout - # At this point, the cache contains the downloaded packages ... - cache restore - # ... so pip does the installation much faster. - pip install -r requirements.txt --cache-dir .pip_cache jobs: - name: Pylint commands: - # list out files that are in directory and working tree - # grep -v will exclude the files being considered for pylint - # grep -E will matches files having .py extension - # This command will help to pass required python files to pylint along with pylint_djanog plugin - # Pylint with -E option will display only if there is any error - - git ls-files | grep -v 'migrations' | grep -v 'settings.py' | grep -v 'manage.py' | grep -E '.py$' | - xargs pylint -E --load-plugins=pylint_django - - - name: "Run Unit Tests" + - git ls-files | grep -v 'migrations' | grep -v 'settings.py' | grep -v 'manage.py' | grep -E '.py$' | xargs pylint -E --load-plugins=pylint_django + - name: Run Unit Tests task: - # This block runs the unit tests. - # Since the test require a database, we start the database here. - # Django automatically creates a test database schema. prologue: commands: - # Start a MySQL database. On Semaphore, databases run in the same - # environment as your code. - # See https://docs.semaphoreci.com/article/32-ubuntu-1804-image#databases-and-services - # Also https://docs.semaphoreci.com/article/54-toolbox-reference#sem-service - sem-service start mysql - checkout - cache restore - pip install -r requirements.txt --cache-dir .pip_cache - # Two parallel test jobs are executed. jobs: - name: Model Test commands: - # Test the application's database models. - - python manage.py test tasks.tests.test_models + - 'python manage.py test tasks.tests.test_models' - name: View Test commands: - # Test the application's views. - - python manage.py test tasks.tests.test_views - - - name: "Run Browser Tests" + - 'python manage.py test tasks.tests.test_views' + env_vars: + - name: DJANGO_TEST_ENV + value: 'true' + - name: Run Browser Tests task: - # This block runs browser-based tests. - # We need to set environment variables. - # See https://docs.semaphoreci.com/article/66-environment-variables-and-secrets env_vars: - name: DB_NAME - value: 'pydjango' - # This test requires the application to be running. - # We start the application server here. + value: pydjango prologue: commands: - # Start MySQL database. - sem-service start mysql - # Install mysql client - sudo apt-get update && sudo apt-get install -y -qq mysql-client - # Create an empty database. - # We can connect to the db with root and a blank password. - mysql --host=0.0.0.0 -uroot -e "create database $DB_NAME" - checkout - cache restore - pip install -r requirements.txt --cache-dir .pip_cache - # Application is started. - - nohup python manage.py runserver 127.0.0.1:8732 & + - 'nohup python manage.py runserver 127.0.0.1:8732 &' jobs: - name: Browser Test commands: - # Run browser tests on Google Chrome. - # On Semaphore, browsers are already installed. - - python manage.py test tasks.tests.test_browser - - - - name: "Run Security Tests" + - '#python manage.py test tasks.tests.test_browser' + - name: Run Security Tests task: - # This block runs through the security checklist for the project. jobs: - name: Deployment Checklist commands: - - checkout - - cache restore - - pip install -r requirements.txt --cache-dir .pip_cache - # Test if project can be deployed securely. - - python manage.py check --deploy --fail-level ERROR + - checkout + - cache restore + - pip install -r requirements.txt --cache-dir .pip_cache + - python manage.py check --deploy --fail-level ERROR diff --git a/README.md b/README.md index d56dc4b..8e97dbb 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,283 @@ -# A Semaphore demo CI/CD pipeline using Python Django - -Example Python Django application and CI/CD pipeline for integrating it with Semaphore 2.0. -This application demonstrates CRUD operations using class based views in Django. It also includes UI for all CRUD views. - -# Local project setup - -1. Run following command to install python pre-requisite for mysqlclient python - ``` - sudo apt-get install python3-dev default-libmysqlclient-dev ### Ubutnu - - sudo yum install python3-devel mysql-devel ### Redhat / CentOS - - brew install mysql-connector-c ### mac os - ``` - for more information on pre-requisite for mysqlclient, visit this page: (https://pypi.org/project/mysqlclient/) - -2. Use anaconda / virtualenv for setting up this project - -3. Install pip requirements - ``` - pip install -r requirements.txt - ``` -4. Create new mysql database - -5. Setup your database credentials and SITE_URL in settings.py file available inside ### pydjango_ci_integration folder - -6. Once you have setup your database, Open command prompt pointing to the Root of the project directory and run following command to create application default database - ``` - (virtualenv / conda environment) > python manage.py migrate - - (virtualenv / conda environment) > python manage.py createsuperuser - ``` -7. Once all of the above command run sucessfully, We are ready to go. Start server by executing command - ``` - (virtualenv / conda environment) > python manage.py runserver 127.0.0.1:8732 - ``` - and visit the web browser with 'http://127.0.0.1:8732' - -## Environment variables - -The following environment variables can be set to override defaults: - -- `SECRET_KEY`: Django [secret key](https://docs.djangoproject.com/en/2.2/ref/settings/#secret-key). -- `DB_ENGINE`: Django database [backend](https://docs.djangoproject.com/en/2.2/ref/databases/). -- `DB_NAME`: database name. -- `DB_HOST`: database hostname. -- `DB_PORT`: database port. -- `DB_USER`: database user. -- `DB_PASSWORD`: database password. - -# CI/CD on Semaphore - -Fork this repository and use it to [create a project](https://docs.semaphoreci.com/article/63-your-first-project) - ``` - curl https://storage.googleapis.com/sem-cli-releases/get.sh | bash - sem connect // found in Semaphore Dashboard - cd - sem init - ``` -The CI pipeline will look like this: - -![pipeline](https://github.com/semaphoreci-demos/semaphore-demo-python-django/blob/master/pydjango_ci_integration/pipepline.png) - -The example pipeline contains 5 blocks: - -* Install Dependencies - * Installs pip requirements -* Run Code Analysis - * Run code analysis / code linting with Pylint -* Run Unit Tests - * Runs Unit Tests with unittest module for views and models file -* Run Browser Tests - * Runs browser tests with python selenium webdriver -* Run Security Tests - * Runs security checklist with Django default deployment checklist - + + +# Django CI/CD with Semaphore and PythonAnywhere + +![Python Version](https://img.shields.io/badge/python-3.8-blue.svg) +![Django Version](https://img.shields.io/badge/django-3.2-green.svg) +![License](https://img.shields.io/github/license/guderian120/semaphore-demo-python-django) +![Last Commit](https://img.shields.io/github/last-commit/guderian120/semaphore-demo-python-django) +![Code Style](https://img.shields.io/badge/code%20style-pylint-yellow.svg) +![Deployed](https://img.shields.io/badge/deployed-PythonAnywhere-lightgrey) + + +# Django CI/CD with Semaphore and PythonAnywhere Live Project +[Live Project here ](https://guderian.pythonanywhere.com) + +This project demonstrates a complete CI/CD pipeline using **Django**, **Semaphore**, and **PythonAnywhere**. It covers development setup, continuous integration, and automated deployment using SSH. + +# Django CI/CD with Semaphore and PythonAnywhere + +This project demonstrates a complete CI/CD pipeline using **Django**, **Semaphore**, and **PythonAnywhere**. It covers development setup, continuous integration, and automated deployment using SSH. + +--- + +## 🧰 Project Setup + +### πŸ“¦ Handling Dependencies + +To avoid deprecated packages and resolve dependency issues with `mysqlclient`, make sure the following system packages are installed: + +```bash +sudo apt-get update +sudo apt-get install python3-dev default-libmysqlclient-dev build-essential pkg-config libssl-dev +``` + +Then install Python dependencies: + +```bash +pip install --upgrade pip setuptools wheel +pip install -r requirements.txt +``` + +### πŸ”§ Swapping Test Runners + +If you're migrating from `django-nose` (which is no longer maintained), uninstall it: + +```bash +pip uninstall django-nose nose +``` + +Switch to `pytest`: + +```bash +pip install pytest pytest-django psycopg2-binary +``` + +Update your `settings.py` to use Django’s default test runner: + +```python +# Remove or comment out these lines: +# TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' +# NOSE_ARGS = [...] + +# Add this: +TEST_RUNNER = 'django.test.runner.DiscoverRunner' +``` + +--- + +## πŸ§ͺ CI with Semaphore + +This project uses Semaphore to automate testing and deployment. Below is the complete `semaphore.yml` configuration: + +```yaml +version: v1.0 +name: Django CI/CD Pipeline +agent: + machine: + type: e1-standard-2 + os_image: ubuntu2004 + +global_job_config: + prologue: + commands: + - sem-version python 3.8 + +blocks: + - name: Install Dependencies + task: + prologue: + commands: + - sudo apt-get update && sudo apt-get install -y python3-dev default-libmysqlclient-dev build-essential pkg-config libssl-dev + - pip install --upgrade pip setuptools wheel + jobs: + - name: pip + commands: + - checkout + - cache restore + - pip download --cache-dir .pip_cache -r requirements.txt + - cache store + env_vars: + - name: DJANGO_TEST_ENV + value: 'true' + + - name: Run Code Analysis + task: + jobs: + - name: Pylint + commands: + - checkout + - cache restore + - pip install -r requirements.txt --cache-dir .pip_cache + - git ls-files | grep -v 'migrations' | grep -v 'settings.py' | grep -v 'manage.py' | grep -E '.py$' | xargs pylint -E --load-plugins=pylint_django + + - name: Run Unit Tests + task: + prologue: + commands: + - sem-service start mysql + jobs: + - name: Model Tests + commands: + - checkout + - cache restore + - pip install -r requirements.txt --cache-dir .pip_cache + - python manage.py test tasks.tests.test_models + - name: View Tests + commands: + - python manage.py test tasks.tests.test_views + env_vars: + - name: DJANGO_TEST_ENV + value: 'true' + + - name: Run Browser Tests + task: + env_vars: + - name: DB_NAME + value: pydjango + prologue: + commands: + - sem-service start mysql + - sudo apt-get update && sudo apt-get install -y -qq mysql-client + - mysql --host=0.0.0.0 -uroot -e "create database $DB_NAME" + - checkout + - cache restore + - pip install -r requirements.txt --cache-dir .pip_cache + - nohup python manage.py runserver 127.0.0.1:8732 & + jobs: + - name: Browser Tests + commands: + - echo "Browser test command goes here" + + - name: Run Security Checks + task: + jobs: + - name: Deployment Checklist + commands: + - checkout + - cache restore + - pip install -r requirements.txt --cache-dir .pip_cache + - python manage.py check --deploy --fail-level ERROR +``` + +--- + +## πŸ›  Conditional Database for Testing + +To ensure smooth CI testing even without internet access to the production database, the settings file uses SQLite for test runs: + +```python +if os.environ.get('DJANGO_TEST_ENV') == 'true': + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ':memory:', + } + } +else: + DATABASES = { + 'default': { + 'ENGINE': os.getenv('DB_ENGINE', 'django.db.backends.mysql'), + 'NAME': os.getenv('DB_NAME', 'None'), + 'USER': os.getenv('DB_USER', 'None'), + 'PASSWORD': os.getenv('DB_PASSWORD', 'None'), + 'HOST': os.getenv('DB_HOST', '127.0.0.1'), + 'PORT': os.getenv('DB_PORT', '3306') + } + } +``` + +--- + +## πŸš€ Deployment to PythonAnywhere (CD) + +### 🐍 Setting up WSGI + +On PythonAnywhere, go to the **Web** tab and create a **manual configuration** web app. Then edit your `wsgi.py`: + +```python +import os +import sys +from dotenv import load_dotenv + +path = '/home/YOUR_USERNAME/semaphore-demo-python-django' +if path not in sys.path: + sys.path.append(path) + +os.environ['DJANGO_SETTINGS_MODULE'] = 'pydjango_ci_integration.settings' + +env_file = os.path.expanduser('~/.env-production') +load_dotenv(env_file) + +from django.core.wsgi import get_wsgi_application +application = get_wsgi_application() +``` + +> Replace `YOUR_USERNAME` and project path accordingly. + +### πŸ”‘ SSH Access (Requires Paid PythonAnywhere Account) + +To enable automated deployment: + +```bash +ssh-copy-id YOUR_USERNAME@ssh.pythonanywhere.com +``` + +--- + +## πŸ”„ CD with Semaphore + +### πŸ” Create Secrets + +1. In Semaphore, go to your project > **Settings > Secrets** +2. Add: + - `SSH_KEY`: Your private SSH key + - `ENV_PRODUCTION`: Your `.env-production` file + +### πŸ“œ `deploy.sh` + +Create a `deploy.sh` file: + +```bash +cd $APP_URL +git fetch --all +git reset --hard origin/$SEMAPHORE_GIT_BRANCH + +source $ENV_FILE +source ~/.virtualenvs/$APP_URL/bin/activate +python manage.py migrate + +touch /var/www/"$(echo $APP_URL | sed 's/\./_/g')"_wsgi.py +``` + +### 🧱 Deployment Block (Semaphore UI) + +1. Add a new block: **Deploy to PythonAnywhere** +2. Set environment variables: + - `SSH_USER = your_pythonanywhere_username` + - `APP_URL = your_username.pythonanywhere.com` + - `ENV_FILE = ~/.env-production` +3. Add the two secrets: `SSH_KEY`, `ENV_PRODUCTION` +4. Under Jobs: + - Name: `Push code` + - Commands: + ```bash + checkout + envsubst < deploy.sh > ~/deploy-production.sh + chmod 0600 ~/.ssh/id_rsa_pa + ssh-keyscan -H ssh.pythonanywhere.com >> ~/.ssh/known_hosts + ssh-add ~/.ssh/id_rsa_pa + scp -oBatchMode=yes ~/.env-production ~/deploy-production.sh $SSH_USER@ssh.pythonanywhere.com + ssh -oBatchMode=yes $SSH_USER@ssh.pythonanywhere.com bash deploy-production.sh + ``` + +--- + +## βœ… Final Thoughts + +With this setup: +- Every push runs linting, unit tests, and security checks +- Deployment is triggered via a CD pipeline using SSH +- Environment-specific settings ensure test safety + +Feel free to fork, clone, and contribute to improve this CI/CD flow for Django deployments. diff --git a/newfile.txt b/newfile.txt new file mode 100644 index 0000000..3b18e51 --- /dev/null +++ b/newfile.txt @@ -0,0 +1 @@ +hello world diff --git a/pydjango_ci_integration/settings.py b/pydjango_ci_integration/settings.py index cb1cd75..1a79f8e 100644 --- a/pydjango_ci_integration/settings.py +++ b/pydjango_ci_integration/settings.py @@ -20,7 +20,7 @@ # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = os.getenv('SECRET_KEY', 'g!^gs#bib&6sn5ow5i&ho0bj4dlz(y%v9!h-fnmh#6h=u_&ip=') +SECRET_KEY = os.getenv('SECRET_KEY', 'None') # SECURITY WARNING: don't run with debug turned on in production! DEBUG = False @@ -39,14 +39,13 @@ 'django.contrib.staticfiles', 'django.contrib.sites', # Contributed apps - 'django_nose', + #'django_nose', # Custom apps 'tasks.apps.TasksConfig', ] -SITE_ID = 1 -SITE_URL = 'http://127.0.0.1:8732/' + MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', @@ -60,6 +59,8 @@ ROOT_URLCONF = 'pydjango_ci_integration.urls' +TEST_RUNNER = 'django.test.runner.DiscoverRunner' # Default Django runner + TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', @@ -82,16 +83,24 @@ # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases -DATABASES = { +if os.environ.get('DJANGO_TEST_ENV') == 'true': + DATABASES = { 'default': { - 'ENGINE': os.getenv('DB_ENGINE', 'django.db.backends.mysql'), - 'NAME': os.getenv('DB_NAME', 'pydjango'), - 'USER': os.getenv('DB_USER', 'root'), - 'PASSWORD': os.getenv('DB_PASSWORD', ''), - 'HOST': os.getenv('DB_HOST', '127.0.0.1'), - 'PORT': os.getenv('DB_PORT', '3306') + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ':test_db:', + } +} +else: + DATABASES = { + 'default': { + 'ENGINE': os.getenv('DB_ENGINE', 'django.db.backends.mysql'), + 'NAME': os.getenv('DB_NAME', 'None'), + 'USER': os.getenv('DB_USER', 'None'), + 'PASSWORD': os.getenv('DB_PASSWORD', 'None'), + 'HOST': os.getenv('DB_HOST', '127.0.0.1'), + 'PORT': os.getenv('DB_PORT', '3306') + } } -} # Password validation @@ -113,17 +122,18 @@ ] # Use nose to run all tests -TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' + # Tell nose to measure coverage on the tasks app -NOSE_ARGS = [ - '--with-coverage', - '--cover-package=tasks' -] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ + +SITE_ID = 1 +SITE_URL = 'http://127.0.0.1:8732/' + + LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' diff --git a/pydjango_ci_integration/urls.py b/pydjango_ci_integration/urls.py index 70d3344..c6fc271 100644 --- a/pydjango_ci_integration/urls.py +++ b/pydjango_ci_integration/urls.py @@ -13,14 +13,15 @@ 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ -from django.conf.urls import url, include +#from django.conf.urls import url, include +from django.urls import path, re_path, include from django.contrib import admin from tasks import views urlpatterns = [ - url(r'^admin/', admin.site.urls), - url('', include('tasks.urls')) + path(r'admin/', admin.site.urls), + path('', include('tasks.urls')) ] handler404 = views.Custom404.as_view() diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..a5f5ac4 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +DJANGO_SETTINGS_MODULE = pydjango_ci_integration.settings +python_files = tasks/tests/test_*.py diff --git a/requirements.txt b/requirements.txt index 750086e..7030dfe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,13 @@ -Django==2.1.7 -mysqlclient==1.4.2 +asgiref==3.8.1 +astroid==2.5 coverage==4.5.2 -django-nose==1.4.6 -nose==1.3.7 +Django==4.0 +mysql-connector-python==8.0.5 +mysqlclient==2.2.7 pylint==2.6.0 pylint-django==2.3.0 pylint-plugin-utils==0.6 -selenium==3.141.0 +pytest==8.3.5 +pytest-django==4.11.1 python-dotenv==0.10.1 +selenium==3.141.0 diff --git a/requirements_old.txt b/requirements_old.txt new file mode 100644 index 0000000..d212ffc --- /dev/null +++ b/requirements_old.txt @@ -0,0 +1,10 @@ +Django==2.1.7 +#mysqlclient==1.4.2 +coverage==4.5.2 +django-nose==1.4.6 +nose==1.3.7 +pylint==2.6.0 +pylint-django==2.3.0 +pylint-plugin-utils==0.6 +selenium==3.141.0 +python-dotenv==0.10.1 diff --git a/tasks/tests/test_models.py b/tasks/tests/test_models.py index 0e7f8e5..f9db68e 100644 --- a/tasks/tests/test_models.py +++ b/tasks/tests/test_models.py @@ -6,6 +6,11 @@ from tasks.models import Task +test_data = { +"task_title":"Development", +"task_description":"This task includes all the developments related activities for this project" +} + class TaskModelTest(TestCase): """ Test Model class diff --git a/virtualenv/bin/Activate.ps1 b/virtualenv/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/virtualenv/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/virtualenv/bin/activate b/virtualenv/bin/activate new file mode 100644 index 0000000..25141eb --- /dev/null +++ b/virtualenv/bin/activate @@ -0,0 +1,70 @@ +# This file must be used with "source bin/activate" *from bash* +# You cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # Call hash to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + hash -r 2> /dev/null + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +# on Windows, a path can contain colons and backslashes and has to be converted: +if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + export VIRTUAL_ENV=$(cygpath /home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv) +else + # use the path as-is + export VIRTUAL_ENV=/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv +fi + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/"bin":$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1='(virtualenv) '"${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT='(virtualenv) ' + export VIRTUAL_ENV_PROMPT +fi + +# Call hash to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +hash -r 2> /dev/null diff --git a/virtualenv/bin/activate.csh b/virtualenv/bin/activate.csh new file mode 100644 index 0000000..5e25fe8 --- /dev/null +++ b/virtualenv/bin/activate.csh @@ -0,0 +1,27 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. + +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV /home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/"bin":$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = '(virtualenv) '"$prompt" + setenv VIRTUAL_ENV_PROMPT '(virtualenv) ' +endif + +alias pydoc python -m pydoc + +rehash diff --git a/virtualenv/bin/activate.fish b/virtualenv/bin/activate.fish new file mode 100644 index 0000000..a43d5db --- /dev/null +++ b/virtualenv/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/). You cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV /home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/"bin $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) '(virtualenv) ' (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT '(virtualenv) ' +end diff --git a/virtualenv/bin/django-admin b/virtualenv/bin/django-admin new file mode 100755 index 0000000..416b95c --- /dev/null +++ b/virtualenv/bin/django-admin @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from django.core.management import execute_from_command_line +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(execute_from_command_line()) diff --git a/virtualenv/bin/get_gprof b/virtualenv/bin/get_gprof new file mode 100755 index 0000000..3169ac3 --- /dev/null +++ b/virtualenv/bin/get_gprof @@ -0,0 +1,75 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# +# Author: Mike McKerns (mmckerns @caltech and @uqfoundation) +# Copyright (c) 2008-2016 California Institute of Technology. +# Copyright (c) 2016-2025 The Uncertainty Quantification Foundation. +# License: 3-clause BSD. The full license text is available at: +# - https://github.com/uqfoundation/dill/blob/master/LICENSE +''' +build profile graph for the given instance + +running: + $ get_gprof + +executes: + gprof2dot -f pstats .prof | dot -Tpng -o .call.png + +where: + are arguments for gprof2dot, such as "-n 5 -e 5" + is code to create the instance to profile + is the class of the instance (i.e. type(instance)) + +For example: + $ get_gprof -n 5 -e 1 "import numpy; numpy.array([1,2])" + +will create 'ndarray.call.png' with the profile graph for numpy.array([1,2]), +where '-n 5' eliminates nodes below 5% threshold, similarly '-e 1' eliminates +edges below 1% threshold +''' + +if __name__ == "__main__": + import sys + if len(sys.argv) < 2: + print ("Please provide an object instance (e.g. 'import math; math.pi')") + sys.exit() + # grab args for gprof2dot + args = sys.argv[1:-1] + args = ' '.join(args) + # last arg builds the object + obj = sys.argv[-1] + obj = obj.split(';') + # multi-line prep for generating an instance + for line in obj[:-1]: + exec(line) + # one-line generation of an instance + try: + obj = eval(obj[-1]) + except Exception: + print ("Error processing object instance") + sys.exit() + + # get object 'name' + objtype = type(obj) + name = getattr(objtype, '__name__', getattr(objtype, '__class__', objtype)) + + # profile dumping an object + import dill + import os + import cProfile + #name = os.path.splitext(os.path.basename(__file__))[0] + cProfile.run("dill.dumps(obj)", filename="%s.prof" % name) + msg = "gprof2dot -f pstats %s %s.prof | dot -Tpng -o %s.call.png" % (args, name, name) + try: + res = os.system(msg) + except Exception: + print ("Please verify install of 'gprof2dot' to view profile graphs") + if res: + print ("Please verify install of 'gprof2dot' to view profile graphs") + + # get stats + f_prof = "%s.prof" % name + import pstats + stats = pstats.Stats(f_prof, stream=sys.stdout) + stats.strip_dirs().sort_stats('cumtime') + stats.print_stats(20) #XXX: save to file instead of print top 20? + os.remove(f_prof) diff --git a/virtualenv/bin/get_objgraph b/virtualenv/bin/get_objgraph new file mode 100755 index 0000000..4c4256d --- /dev/null +++ b/virtualenv/bin/get_objgraph @@ -0,0 +1,54 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# +# Author: Mike McKerns (mmckerns @caltech and @uqfoundation) +# Copyright (c) 2008-2016 California Institute of Technology. +# Copyright (c) 2016-2025 The Uncertainty Quantification Foundation. +# License: 3-clause BSD. The full license text is available at: +# - https://github.com/uqfoundation/dill/blob/master/LICENSE +""" +display the reference paths for objects in ``dill.types`` or a .pkl file + +Notes: + the generated image is useful in showing the pointer references in + objects that are or can be pickled. Any object in ``dill.objects`` + listed in ``dill.load_types(picklable=True, unpicklable=True)`` works. + +Examples:: + + $ get_objgraph ArrayType + Image generated as ArrayType.png +""" + +import dill as pickle +#pickle.debug.trace(True) +#import pickle + +# get all objects for testing +from dill import load_types +load_types(pickleable=True,unpickleable=True) +from dill import objects + +if __name__ == "__main__": + import sys + if len(sys.argv) != 2: + print ("Please provide exactly one file or type name (e.g. 'IntType')") + msg = "\n" + for objtype in list(objects.keys())[:40]: + msg += objtype + ', ' + print (msg + "...") + else: + objtype = str(sys.argv[-1]) + try: + obj = objects[objtype] + except KeyError: + obj = pickle.load(open(objtype,'rb')) + import os + objtype = os.path.splitext(objtype)[0] + try: + import objgraph + objgraph.show_refs(obj, filename=objtype+'.png') + except ImportError: + print ("Please install 'objgraph' to view object graphs") + + +# EOF diff --git a/virtualenv/bin/isort b/virtualenv/bin/isort new file mode 100755 index 0000000..aba968d --- /dev/null +++ b/virtualenv/bin/isort @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from isort.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/virtualenv/bin/isort-identify-imports b/virtualenv/bin/isort-identify-imports new file mode 100755 index 0000000..26e108d --- /dev/null +++ b/virtualenv/bin/isort-identify-imports @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from isort.main import identify_imports_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(identify_imports_main()) diff --git a/virtualenv/bin/pip b/virtualenv/bin/pip new file mode 100755 index 0000000..9a7265a --- /dev/null +++ b/virtualenv/bin/pip @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/virtualenv/bin/pip3 b/virtualenv/bin/pip3 new file mode 100755 index 0000000..9a7265a --- /dev/null +++ b/virtualenv/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/virtualenv/bin/pip3.12 b/virtualenv/bin/pip3.12 new file mode 100755 index 0000000..9a7265a --- /dev/null +++ b/virtualenv/bin/pip3.12 @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/virtualenv/bin/py.test b/virtualenv/bin/py.test new file mode 100755 index 0000000..fa5868a --- /dev/null +++ b/virtualenv/bin/py.test @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pytest import console_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(console_main()) diff --git a/virtualenv/bin/pylint b/virtualenv/bin/pylint new file mode 100755 index 0000000..1e56c4e --- /dev/null +++ b/virtualenv/bin/pylint @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pylint import run_pylint +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run_pylint()) diff --git a/virtualenv/bin/pylint-config b/virtualenv/bin/pylint-config new file mode 100755 index 0000000..1d36288 --- /dev/null +++ b/virtualenv/bin/pylint-config @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pylint import _run_pylint_config +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(_run_pylint_config()) diff --git a/virtualenv/bin/pyreverse b/virtualenv/bin/pyreverse new file mode 100755 index 0000000..8aa2d54 --- /dev/null +++ b/virtualenv/bin/pyreverse @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pylint import run_pyreverse +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run_pyreverse()) diff --git a/virtualenv/bin/pytest b/virtualenv/bin/pytest new file mode 100755 index 0000000..fa5868a --- /dev/null +++ b/virtualenv/bin/pytest @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pytest import console_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(console_main()) diff --git a/virtualenv/bin/python b/virtualenv/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/virtualenv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/virtualenv/bin/python3 b/virtualenv/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/virtualenv/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/virtualenv/bin/python3.12 b/virtualenv/bin/python3.12 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/virtualenv/bin/python3.12 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/virtualenv/bin/sqlformat b/virtualenv/bin/sqlformat new file mode 100755 index 0000000..e6bc128 --- /dev/null +++ b/virtualenv/bin/sqlformat @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from sqlparse.__main__ import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/virtualenv/bin/symilar b/virtualenv/bin/symilar new file mode 100755 index 0000000..be7bca9 --- /dev/null +++ b/virtualenv/bin/symilar @@ -0,0 +1,8 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pylint import run_symilar +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run_symilar()) diff --git a/virtualenv/bin/undill b/virtualenv/bin/undill new file mode 100755 index 0000000..387cebc --- /dev/null +++ b/virtualenv/bin/undill @@ -0,0 +1,22 @@ +#!/home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv/bin/python3 +# +# Author: Mike McKerns (mmckerns @caltech and @uqfoundation) +# Copyright (c) 2008-2016 California Institute of Technology. +# Copyright (c) 2016-2025 The Uncertainty Quantification Foundation. +# License: 3-clause BSD. The full license text is available at: +# - https://github.com/uqfoundation/dill/blob/master/LICENSE +""" +unpickle the contents of a pickled object file + +Examples:: + + $ undill hello.pkl + ['hello', 'world'] +""" + +if __name__ == '__main__': + import sys + import dill + for file in sys.argv[1:]: + print (dill.load(open(file,'rb'))) + diff --git a/virtualenv/lib64 b/virtualenv/lib64 new file mode 120000 index 0000000..7951405 --- /dev/null +++ b/virtualenv/lib64 @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/virtualenv/pyvenv.cfg b/virtualenv/pyvenv.cfg new file mode 100644 index 0000000..ff4655e --- /dev/null +++ b/virtualenv/pyvenv.cfg @@ -0,0 +1,5 @@ +home = /usr/bin +include-system-site-packages = false +version = 3.12.3 +executable = /usr/bin/python3.12 +command = /usr/bin/python3 -m venv /home/guderian/AMALITECH_GTP/self_paced_projects/semaphore_python/semaphore-demo-python-django/virtualenv