Skip to content

Number of jobs affects score #1387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Xylon2 opened this issue Mar 21, 2017 · 6 comments · Fixed by #4007
Closed

Number of jobs affects score #1387

Xylon2 opened this issue Mar 21, 2017 · 6 comments · Fixed by #4007
Labels

Comments

@Xylon2
Copy link

Xylon2 commented Mar 21, 2017

Steps to reproduce

I don't know if this bug happens with all code but it happens with the Taskenizer code tree:
$ fossil clone https://www.suckmore.uk/cgi-bin/repo/Taskenizer ~/tasrepo.fossil
$ mkdir taskenizer
$ cd taskenizer
$ fossil open ~/tasrepo.fossil
$ pylint3 --rcfile='pylintrc' taskenizer/

Now edit the jobs to 1 in pylintrc and run again

Current behavior

Score changes

Expected behavior

Changing number of jobs should not affect score.

pylint --version output

pylint3 1.5.2,
astroid 1.4.4
Python 3.4.2 (default, Oct 8 2014, 10:45:20)
[GCC 4.9.1]

@PCManticore
Copy link
Contributor

Can you try running with pylint 1.6.4 and see if this still reproduces?

@Xylon2
Copy link
Author

Xylon2 commented Mar 23, 2017

OK I did that, still reproduces.

With 1 job my score is 8.95 and with 2 or more my score is 9.13

@rogalski
Copy link
Contributor

rogalski commented Apr 2, 2017

@Xylon2 Can you run diff on summary between two runs and include results here?

Accoring to my experiment, only thing missed by us is bunch of duplicated-code messages.

+---------------------------+------------+
|duplicate-code             |56          |
+---------------------------+------------+

Looking at multiprocessing code - it's quite obvious it won't work right now - all modules are put on queue and consumed independently, while duplicated code checker has to have multiple files on input for it to work. We would have to differentiate between parallable and not parrallable checkers and handle them in different way.

@Xylon2
Copy link
Author

Xylon2 commented Apr 5, 2017

$ pylint --version
No config file found, using default configuration
pylint 2.0.0,
astroid 1.5.0
Python 3.6.0 (default, Jan 16 2017, 12:12:55)
[GCC 6.3.1 20170109]

$ diff 2threads 1threads
0a1,18
> ************* Module taskenizer.taskenizer
> C:  1, 0: Missing module docstring (missing-docstring)
> C: 41, 0: Invalid constant name "config_file" (invalid-name)
> C: 42, 0: Invalid constant name "javascript_name" (invalid-name)
> C: 43, 0: Invalid constant name "source_tarball_name" (invalid-name)
> C: 48, 0: Invalid constant name "conf" (invalid-name)
> W: 52, 0: Access to a protected member _interpolation of a client class (protected-access)
> C: 58, 0: Import "from taskenizer.functions import operations" should be placed at the top of the module (wrong-import-position)
> C: 59, 0: Import "from taskenizer.functions import task_funcs" should be placed at the top of the module (wrong-import-position)
> C: 60, 0: Import "from taskenizer.pages import landing" should be placed at the top of the module (wrong-import-position)
> C: 70, 0: Invalid constant name "dbconn" (invalid-name)
> C: 71, 0: Invalid constant name "conn" (invalid-name)
> C: 76, 0: Invalid constant name "templates" (invalid-name)
> C: 81, 0: Invalid constant name "installtheme" (invalid-name)
> R: 84, 0: Too many local variables (31/15) (too-many-locals)
> R: 84, 0: Too many branches (18/12) (too-many-branches)
> R: 84, 0: Too many statements (86/50) (too-many-statements)
> C:375, 0: Missing function docstring (missing-docstring)
39,56d56
< ************* Module taskenizer.taskenizer
< C:  1, 0: Missing module docstring (missing-docstring)
< C: 41, 0: Invalid constant name "config_file" (invalid-name)
< C: 42, 0: Invalid constant name "javascript_name" (invalid-name)
< C: 43, 0: Invalid constant name "source_tarball_name" (invalid-name)
< C: 48, 0: Invalid constant name "conf" (invalid-name)
< W: 52, 0: Access to a protected member _interpolation of a client class (protected-access)
< C: 58, 0: Import "from taskenizer.functions import operations" should be placed at the top of the module (wrong-import-position)
< C: 59, 0: Import "from taskenizer.functions import task_funcs" should be placed at the top of the module (wrong-import-position)
< C: 60, 0: Import "from taskenizer.pages import landing" should be placed at the top of the module (wrong-import-position)
< C: 70, 0: Invalid constant name "dbconn" (invalid-name)
< C: 71, 0: Invalid constant name "conn" (invalid-name)
< C: 76, 0: Invalid constant name "templates" (invalid-name)
< C: 81, 0: Invalid constant name "installtheme" (invalid-name)
< R: 84, 0: Too many local variables (31/15) (too-many-locals)
< R: 84, 0: Too many branches (18/12) (too-many-branches)
< R: 84, 0: Too many statements (86/50) (too-many-statements)
< C:375, 0: Missing function docstring (missing-docstring)
72,78d71
< ************* Module taskenizer.mini_pages.modify_note_page
< C:  1, 0: Missing module docstring (missing-docstring)
< C: 19, 0: Missing function docstring (missing-docstring)
< R: 19, 0: Too many arguments (9/5) (too-many-arguments)
< R: 19, 0: Too many local variables (28/15) (too-many-locals)
< R: 57, 4: Too many nested blocks (6/5) (too-many-nested-blocks)
< R: 19, 0: Too many branches (15/12) (too-many-branches)
86a80,86
> ************* Module taskenizer.mini_pages.modify_note_page
> C:  1, 0: Missing module docstring (missing-docstring)
> C: 19, 0: Missing function docstring (missing-docstring)
> R: 19, 0: Too many arguments (9/5) (too-many-arguments)
> R: 19, 0: Too many local variables (28/15) (too-many-locals)
> R: 57, 4: Too many nested blocks (6/5) (too-many-nested-blocks)
> R: 19, 0: Too many branches (15/12) (too-many-branches)
100,103d99
< ************* Module taskenizer.pages.landing
< C:  1, 0: Missing module docstring (missing-docstring)
< C: 19, 0: Missing function docstring (missing-docstring)
< R: 19, 0: Too many arguments (6/5) (too-many-arguments)
108a105,108
> ************* Module taskenizer.pages.landing
> C:  1, 0: Missing module docstring (missing-docstring)
> C: 19, 0: Missing function docstring (missing-docstring)
> R: 19, 0: Too many arguments (6/5) (too-many-arguments)
123a124,129
> ************* Module taskenizer.pages.register
> C: 49, 0: Line too long (109/100) (line-too-long)
> C:  1, 0: Missing module docstring (missing-docstring)
> C: 19, 0: Missing function docstring (missing-docstring)
> R: 19, 0: Too many arguments (7/5) (too-many-arguments)
> R: 19, 0: Too many local variables (21/15) (too-many-locals)
135,140d140
< ************* Module taskenizer.pages.register
< C: 49, 0: Line too long (109/100) (line-too-long)
< C:  1, 0: Missing module docstring (missing-docstring)
< C: 19, 0: Missing function docstring (missing-docstring)
< R: 19, 0: Too many arguments (7/5) (too-many-arguments)
< R: 19, 0: Too many local variables (21/15) (too-many-locals)
271,278d270
< ************* Module taskenizer.functions.crypto
< C:  1, 0: Missing module docstring (missing-docstring)
< C: 19, 0: Missing function docstring (missing-docstring)
< R: 19, 0: Too many local variables (19/15) (too-many-locals)
< R: 36, 4: Unnecessary "else" after "return" (no-else-return)
< C: 36, 7: Do not use `len(SEQUENCE)` as condition value (len-as-condition)
< C: 63, 0: Missing function docstring (missing-docstring)
< C: 81, 0: Missing function docstring (missing-docstring)
309a302,1093
> ************* Module taskenizer.functions.crypto
> C:  1, 0: Missing module docstring (missing-docstring)
> C: 19, 0: Missing function docstring (missing-docstring)
> R: 19, 0: Too many local variables (19/15) (too-many-locals)
> R: 36, 4: Unnecessary "else" after "return" (no-else-return)
> C: 36, 7: Do not use `len(SEQUENCE)` as condition value (len-as-condition)
> C: 63, 0: Missing function docstring (missing-docstring)
> C: 81, 0: Missing function docstring (missing-docstring)
> ************* Module taskenizer.functions.__init__
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.modify_auto_habit_page:19
> ==taskenizer.mini_pages.modify_manu_habit_page:19
>                            conf, javascript_name, themeinfo):
>     from taskenizer.functions import display
>     from taskenizer.functions import crypto
>     from taskenizer.functions import operations
>     import re
> 
>     return_value = ''
> 
>     # Make sure something was posted because this page cannot work at
>     # all otherwize.
>     if 'data-category' not in form:
>         return_value += 1 / 0  # halt and catch fire
> 
>         return 'Error'
> 
>     error_msg = ''
> 
>     # We need to find out the id of the habits so we find the first habit
>     for key in form:
>         if re.search('^taskid_', key):
>             habit_id = form[key].value
> 
>             if habit_id == '':
>                 raise ValueError("ID missing :S.")  # bot attack?
> 
>             break
> 
>     # Find out what category this habit belongs to
>     tup = (habit_id,)
>     conn.execute('''SELECT cat_id (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.ac_deletion:41
> ==taskenizer.mini_pages.modify_username:59
>             tup = (user_id,)
>             conn.execute('''SELECT passhash, salt
>                          FROM User
>                          WHERE id = ?''', tup)
>             ans = conn.fetchone()
>             correcthash = ans[0]
>             salt = base64.b64decode(ans[1].encode('ASCII'))
>             # The password will be utf-8 encoded before being hashed
>             enc_passw = passw.encode('utf-8')
> 
>             from cryptography.hazmat.primitives import hashes
>             from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
>             from cryptography.hazmat.backends import default_backend
>             backend = default_backend()
> 
>             kdf = PBKDF2HMAC(
>                 algorithm=hashes.SHA256(),
>                 length=32,
>                 salt=salt,
>                 iterations=100000,
>                 backend=backend
>             )
> 
>             passhash = kdf.derive(enc_passw)
> 
>             if passhash != correcthash:
>                 raise ValueError("Incorrect password.")
> 
>             # Well, all the sanity checks passed so we can now change
>             # their username :) (duplicate-code)
> R:  1, 0: Similar lines in 3 files
> ==taskenizer.mini_pages.ac_deletion:45
> ==taskenizer.mini_pages.del_other:45
> ==taskenizer.mini_pages.modify_username:63
>             ans = conn.fetchone()
>             correcthash = ans[0]
>             salt = base64.b64decode(ans[1].encode('ASCII'))
>             # The password will be utf-8 encoded before being hashed
>             enc_passw = passw.encode('utf-8')
> 
>             from cryptography.hazmat.primitives import hashes
>             from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
>             from cryptography.hazmat.backends import default_backend
>             backend = default_backend()
> 
>             kdf = PBKDF2HMAC(
>                 algorithm=hashes.SHA256(),
>                 length=32,
>                 salt=salt,
>                 iterations=100000,
>                 backend=backend
>             )
> 
>             passhash = kdf.derive(enc_passw)
> 
>             if passhash != correcthash:
>                 raise ValueError("Incorrect password.")
> 
>             # Well, all the sanity checks passed so we can now change
>             # their username :) (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.add_auto_habit_page:19
> ==taskenizer.mini_pages.add_deferred_note_page:19
>                            cryptohash, conf, javascript_name, themeinfo):
>     from taskenizer.functions import display
>     from taskenizer.functions import operations
> 
>     return_value = ''
> 
>     # Make sure something was posted because this page cannot work at
>     # all otherwize.
>     if 'data-category' not in form:
>         return_value += 1 / 0  # halt and catch fire
> 
>         return 'Error'
> 
>     error_msg = ''
> 
>     # user's timezone
>     timezone = operations.get_tz_settings(conn, user_id)
> 
>     # I need to find the current year, month and day to be the default.
>     tznorm = operations.tz_normalize(cur_time, timezone)
> 
>     year = tznorm.year
>     month = tznorm.month
>     day = tznorm.day
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.ac_deletion:19
> ==taskenizer.mini_pages.del_other:19
>                 javascript_name, themeinfo):
>     from taskenizer.functions import display
>     import base64
> 
>     return_value = ''
> 
>     error_msg = ''
> 
>     # Has the user entered something yet? If not then the page has
>     # just loaded.
>     if 'button-pressed' in form:
>         # Here I will sanity check the fields. If a sanity check fails
>         # I set `error_msg'. If all the checks pass we delete the
>         # account.
> 
>         try:
>             try:
>                 passw = form['cur_pass'].value
>             except KeyError:
>                 raise ValueError("An error has occured.")
> 
>             # Password check
>             tup = (user_id,)
>             conn.execute('''SELECT passhash, salt
>                          FROM User (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.modify_auto_habit_page:60
> ==taskenizer.mini_pages.modify_manu_habit_page:60
>                                                  conf, javascript_name,
>                                                  themeinfo['activetheme'])
>         return_value += '<h2>Category access denied</h2>'
> 
>         return return_value
> 
>     # Has the user entered something yet? If not then the page has
>     # just loaded.
>     if 'button-pressed' in form:
>         try:
>             for key in form:
>                 if re.search('^taskid_', key):
>                     itnum = re.sub('_categ_.+', '',
>                                    re.sub('^taskid_', '', key))
>                     tasid = form[key].value
> 
>                     item = (itnum, tasid)
>  (duplicate-code)
> R:  1, 0: Similar lines in 3 files
> ==taskenizer.mini_pages.modify_auto_habit_page:19
> ==taskenizer.mini_pages.modify_manu_habit_page:19
> ==taskenizer.mini_pages.move_page:19
>                            conf, javascript_name, themeinfo):
>     from taskenizer.functions import display
>     from taskenizer.functions import crypto
>     from taskenizer.functions import operations
>     import re
> 
>     return_value = ''
> 
>     # Make sure something was posted because this page cannot work at
>     # all otherwize.
>     if 'data-category' not in form:
>         return_value += 1 / 0  # halt and catch fire
> 
>         return 'Error'
> 
>     error_msg = ''
> 
>     # We need to find out the id of the habits so we find the first habit (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.display:217
> ==taskenizer.pages.main:132
>                 list_of_habits = operations.gen_auto_habit_display_list(conn,
>                                                                         cat_id,
>                                                                         fern,
>                                                                         cur_time,
>                                                                         timezone
>                                                                        )
> 
>                 # We decide whether to display move buttons or
>                 # not. There's no point of displaying them if there's
>                 # only one category.
>                 tup = (1, user_id,)
>                 conn.execute('''SELECT COUNT(*)
>                              FROM CatKey
>                              WHERE task_type = ?
>                              AND user_id = ?;''', tup)
>                 num_cats = conn.fetchone()
>  (duplicate-code)
> R:  1, 0: Similar lines in 3 files
> ==taskenizer.mini_pages.modify_auto_habit_page:25
> ==taskenizer.mini_pages.modify_manu_habit_page:25
> ==taskenizer.mini_pages.modify_note_page:25
>     return_value = ''
> 
>     # Make sure something was posted because this page cannot work at
>     # all otherwize.
>     if 'data-category' not in form:
>         return_value += 1 / 0  # halt and catch fire
> 
>         return 'Error'
> 
>     error_msg = ''
> 
>     # We need to find out the id of the habits so we find the first habit
>     for key in form:
>         if re.search('^taskid_', key): (duplicate-code)
> R:  1, 0: Similar lines in 4 files
> ==taskenizer.mini_pages.ac_deletion:23
> ==taskenizer.mini_pages.del_other:23
> ==taskenizer.mini_pages.modify_pass:29
> ==taskenizer.mini_pages.modify_username:24
>     return_value = ''
> 
>     error_msg = ''
> 
>     # Has the user entered something yet? If not then the page has
>     # just loaded.
>     if 'button-pressed' in form:
>         # Here I will sanity check the fields. If a sanity check fails
>         # I set `error_msg'. If all the checks pass we change the
>         # password to that value.
> 
>         try:
>             try: (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.modify_biscuit_page:32
> ==taskenizer.mini_pages.modify_note_page:61
>         if 'button-pressed' in form:
>             # Here I will first sanity check all notes to check none
>             # are empty. Then, one by one, modify the notes.
>             # If the sanity check fails we will set `error_msg'.
>             try:
>                 valid_items = []
> 
>                 for key in form:
>                     if re.search('^taskid_', key):
>                         itnum = re.sub('_categ_.+', '',
>                                        re.sub('^taskid_', '', key))
>                         new_name = form["new-value_" + itnum].value (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.modify_auto_habit_page:91
> ==taskenizer.mini_pages.modify_manu_habit_page:91
>                                              themeinfo['activetheme'])
> 
>     # I need to get the data from the database.
>     habits = []
> 
>     for key in form:
>         if re.search('^taskid_', key):
>             # The template needs an ID, frequency, frequency units,
>             # days, months, years, and a text content
>             tasid = form[key].value
> 
>             tup = (tasid,) (duplicate-code)
> R:  1, 0: Similar lines in 6 files
> ==taskenizer.mini_pages.add_auto_habit_page:23
> ==taskenizer.mini_pages.add_deferred_note_page:23
> ==taskenizer.mini_pages.modify_auto_habit_page:25
> ==taskenizer.mini_pages.modify_manu_habit_page:25
> ==taskenizer.mini_pages.modify_note_page:25
> ==taskenizer.mini_pages.move_page:25
>     return_value = ''
> 
>     # Make sure something was posted because this page cannot work at
>     # all otherwize.
>     if 'data-category' not in form:
>         return_value += 1 / 0  # halt and catch fire
> 
>         return 'Error'
> 
>     error_msg = ''
> 
>     # We need to find out the id of the habits so we find the first habit (duplicate-code)
> R:  1, 0: Similar lines in 4 files
> ==taskenizer.functions.operations:1386
> ==taskenizer.mini_pages.ac_deletion:54
> ==taskenizer.mini_pages.del_other:54
> ==taskenizer.mini_pages.modify_username:72
>             backend = default_backend()
> 
>             kdf = PBKDF2HMAC(
>                 algorithm=hashes.SHA256(),
>                 length=32,
>                 salt=salt,
>                 iterations=100000,
>                 backend=backend
>             )
> 
>             passhash = kdf.derive(enc_passw)
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.operations:744
> ==taskenizer.functions.process_data:388
>                             user_id
>                         ]
> 
>                         conn.execute('''INSERT INTO Note
>                                      (id, cat_id, color, name, deferred,
>                                      def_days, def_months, def_years, user_id)
>                                      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)''', to_be_inserted)
> 
>                         inc_change_num(conn, 0, form["data-category"].value, None)
> 
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.operations:523
> ==taskenizer.functions.process_data:1250
>                         class ValueAdd:
> 
>                             def __init__(self, value):
>                                 self.value = value
> 
>                         # The `add_auto_habit' function requires a `form'
>                         # dictionary. I will make a fake one for it here.
>                         fake_form = {
>                             'habit-name_1': ValueAdd(name),
>                             "frequency_1": ValueAdd(freq),
>                             "freq-units_1": ValueAdd(freq_units), (duplicate-code)
> R:  1, 0: Similar lines in 8 files
> ==taskenizer.mini_pages.add_auto_habit_page:23
> ==taskenizer.mini_pages.add_deferred_note_page:23
> ==taskenizer.mini_pages.add_manu_habit_page:23
> ==taskenizer.mini_pages.defer_task_page:25
> ==taskenizer.mini_pages.modify_auto_habit_page:25
> ==taskenizer.mini_pages.modify_manu_habit_page:25
> ==taskenizer.mini_pages.modify_note_page:25
> ==taskenizer.mini_pages.move_page:25
>     return_value = ''
> 
>     # Make sure something was posted because this page cannot work at
>     # all otherwize.
>     if 'data-category' not in form:
>         return_value += 1 / 0  # halt and catch fire
> 
>         return 'Error'
> 
>     error_msg = ''
>  (duplicate-code)
> R:  1, 0: Similar lines in 5 files
> ==taskenizer.functions.operations:1386
> ==taskenizer.mini_pages.ac_deletion:54
> ==taskenizer.mini_pages.del_other:54
> ==taskenizer.mini_pages.modify_pass:73
> ==taskenizer.mini_pages.modify_username:72
>             backend = default_backend()
> 
>             kdf = PBKDF2HMAC(
>                 algorithm=hashes.SHA256(),
>                 length=32,
>                 salt=salt,
>                 iterations=100000,
>                 backend=backend
>             )
> 
>             passhash = kdf.derive(enc_passw) (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.operations:523
> ==taskenizer.functions.process_data:1442
>                         class ValueAdd:
> 
>                             def __init__(self, value):
>                                 self.value = value
> 
>                         # The `add_manu_habit' function requires a `form'
>                         # dictionary. I will make a fake one for it here.
>                         fake_form = {
>                             'habit-name_1': ValueAdd(name),
>                             "frequency_1": ValueAdd(freq), (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.modify_pass:150
> ==taskenizer.mini_pages.share_cat:165
>                 backend = default_backend()
>                 cipher = Cipher(algorithms.AES(cryptohash),
>                                 modes.OFB(cur_iv), backend=backend)
> 
>                 decryptor = cipher.decryptor()
> 
>                 cryptokey = decryptor.update(key) + decryptor.finalize()
> 
>             # Make a new CatKey entry.
>  (duplicate-code)
> R:  1, 0: Similar lines in 7 files
> ==taskenizer.functions.operations:1386
> ==taskenizer.mini_pages.ac_deletion:54
> ==taskenizer.mini_pages.del_other:54
> ==taskenizer.mini_pages.modify_pass:73
> ==taskenizer.mini_pages.modify_username:72
> ==taskenizer.mini_pages.share_cat:115
> ==taskenizer.mini_pages.share_cat:85
>             backend = default_backend()
> 
>             kdf = PBKDF2HMAC(
>                 algorithm=hashes.SHA256(),
>                 length=32,
>                 salt=salt,
>                 iterations=100000,
>                 backend=backend
>             )
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.operations:724
> ==taskenizer.functions.process_data:368
>     color = conf['Cosmetic']['default_defered_task_background_color']
> 
>     fern = crypto.prepare_cryptor(conn, user_id, cryptohash, 0, form[
>                                "data-category"].value)
> 
>     if fern is None or isinstance(fern, (bool,)):
>         raise Exception("Category access denied.")
> 
>     # Encrypt the name (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.display:121
> ==taskenizer.pages.main:86
>                 list_of_notes = operations.gen_note_display_list(conn, cat_id, fern)
> 
>                 # We need to decide whether to display move buttons or
>                 # not. There's no point of displaying them if there's
>                 # only one category.
>                 tup = (0, user_id,)
>                 conn.execute('''SELECT COUNT(*)
>                              FROM CatKey
>                              WHERE task_type = ? (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.pages.auto_habits:33
> ==taskenizer.pages.manu_habits:33
>     conn.execute('''SELECT cat_id
>                  FROM CatKey
>                  WHERE task_type = ?
>                  AND user_id = ?
>                  ORDER BY id ASC;''', tup)
> 
>     cats = []
>     for tup in conn.fetchall():
>         conn.execute('''SELECT id, name (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.operations:1417
> ==taskenizer.pages.configuration:350
>     tup = (
>         user_id,
>         session_id,
>         cur_time
>     )
> 
>     conn.execute('''SELECT COUNT(*)
>                  FROM Session
>                  WHERE user_id = ? (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.crypto:27
> ==taskenizer.mini_pages.share_cat:147
>         tup = (cat_type, str(cat_id), user_id)
>         conn.execute('''SELECT iv, key
>                      FROM CatKey
>                      WHERE task_type = ?
>                      AND cat_id = ?
>                      AND user_id = ?;''', tup)
>         ans = conn.fetchall()
> 
>     if len(ans) == 0: (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.modify_pass:48
> ==taskenizer.mini_pages.modify_username:38
>             except KeyError:
>                 raise ValueError("An error has occured.")
> 
>             try:
>                 passw = form['cur_pass'].value
>             except KeyError:
>                 raise ValueError("An error has occured.")
> 
>             # New password checks (duplicate-code)
> R:  1, 0: Similar lines in 3 files
> ==taskenizer.mini_pages.add_auto_habit_page:35
> ==taskenizer.mini_pages.add_deferred_note_page:35
> ==taskenizer.mini_pages.defer_task_page:114
>         timezone = operations.get_tz_settings(conn, user_id)
> 
>         # I need to find the current year, month and day to be the default.
>         tznorm = operations.tz_normalize(cur_time, timezone)
> 
>         year = tznorm.year
>         month = tznorm.month
>         day = tznorm.day
>  (duplicate-code)
> R:  1, 0: Similar lines in 4 files
> ==taskenizer.functions.operations:765
> ==taskenizer.functions.operations:880
> ==taskenizer.functions.operations:984
> ==taskenizer.functions.process_data:254
>                     if form["task-next-year_" + itnum].value == '':
>                         raise ValueError('Missing year value.')
>                     if form["task-next-month_" + itnum].value == '':
>                         raise ValueError('Missing month value.')
>                     if form["task-next-day_" + itnum].value == '':
>                         raise ValueError('Missing day value.')
> 
>                     # Raises appropriate ValueError if invalid (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.display:171
> ==taskenizer.pages.biscuits:46
>     tup = (user_id,)
>     conn.execute('''SELECT id, color, name, timestamp
>                  FROM Biscuit
>                  WHERE user_id = ?
>                  ORDER BY id DESC;''', tup)
>     rows = conn.fetchall()
> 
>     # Decrypt the names (duplicate-code)
> R:  1, 0: Similar lines in 3 files
> ==taskenizer.mini_pages.ac_deletion:41
> ==taskenizer.mini_pages.modify_pass:61
> ==taskenizer.mini_pages.modify_username:59
>             tup = (user_id,)
>             conn.execute('''SELECT passhash, salt
>                          FROM User
>                          WHERE id = ?''', tup)
>             ans = conn.fetchone()
>             correcthash = ans[0]
>             salt = base64.b64decode(ans[1].encode('ASCII'))
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.del_other:41
> ==taskenizer.mini_pages.share_cat:72
>             tup = (user_id,)
>             conn.execute('''SELECT passhash, salt
>                          FROM User
>                          WHERE id = ?;''', tup)
>             ans = conn.fetchone()
>             correcthash = ans[0]
>             salt = base64.b64decode(ans[1].encode('ASCII'))
>             # The password will be utf-8 encoded before being hashed (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.task_funcs:450
> ==taskenizer.taskenizer:204
>                                                   int(conf['Cosmetic']
>                                                       ['login_days'])
>                                                   )
> 
>             expires = humbe[0]
>             ex_head = humbe[1]
> 
>             # Make a session (duplicate-code)
> R:  1, 0: Similar lines in 4 files
> ==taskenizer.functions.operations:869
> ==taskenizer.functions.operations:973
> ==taskenizer.functions.process_data:528
> ==taskenizer.functions.process_data:801
>         for key in form:
>             if re.search('^dataid_', key):
>                 try:
>                     itnum = re.sub('_categ_.+', '',
>                                    re.sub('^dataid_', '', key))
>                     tasid = form[key].value
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.pages.main:191
> ==taskenizer.pages.manu_habits:58
>                 tup = (2, user_id,)
>                 conn.execute('''SELECT COUNT(*)
>                              FROM CatKey
>                              WHERE task_type = ?
>                              AND user_id = ?;''', tup)
>                 num_cats = conn.fetchone()
>  (duplicate-code)
> R:  1, 0: Similar lines in 3 files
> ==taskenizer.functions.display:227
> ==taskenizer.pages.auto_habits:58
> ==taskenizer.pages.main:142
>             tup = (1, user_id,)
>             conn.execute('''SELECT COUNT(*)
>                          FROM CatKey
>                          WHERE task_type = ?
>                          AND user_id = ?;''', tup)
>             num_cats = conn.fetchone()
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.pages.auto_habits:59
> ==taskenizer.pages.manu_habits:59
>             conn.execute('''SELECT COUNT(*)
>                          FROM CatKey
>                          WHERE task_type = ?
>                          AND user_id = ?;''', tup)
>             num_cats = conn.fetchone()
> 
>             tup = (cat_id,) (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.pages.auto_habits:43
> ==taskenizer.pages.manu_habits:43
>                      WHERE id = ?;''', tup)
>         cats += conn.fetchall()
> 
>     for cat in cats:
>         cat_id = cat[0]
>         cat_name = cat[1]
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.operations:1228
> ==taskenizer.pages.deferred_tasks:121
>     if task_type == 0:
>         cat_type = 'Note'
>     if task_type == 1:
>         cat_type = 'AutoHabit'
>     if task_type == 2:
>         cat_type = 'ManuHabit'
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.display:183
> ==taskenizer.pages.biscuits:58
>         num_note_cats=num_note_cats,
>         query_string=environ['QUERY_STRING'],
>         rows=rows,
>         defcolor=conf['Cosmetic']['default_task_background_color'],
>         request_uri=environ['REQUEST_URI']
>     )
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.display:126
> ==taskenizer.pages.biscuits:38
>         tup = (0, user_id,)
>         conn.execute('''SELECT COUNT(*)
>                      FROM CatKey
>                      WHERE task_type = ?
>                      AND user_id = ?;''', tup)
>         num_note_cats = conn.fetchone()
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.modify_auto_habit_page:114
> ==taskenizer.mini_pages.modify_manu_habit_page:113
>         error_msg=error_msg,
>         request_uri=environ['REQUEST_URI'],
>         cat=form['data-category'].value,
>         habits=habits,
>     )
> 
>     return return_value (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.mini_pages.add_auto_habit_page:73
> ==taskenizer.mini_pages.add_manu_habit_page:60
>         error_msg=error_msg,
>         request_uri=environ['REQUEST_URI'],
>         cat=form['data-category'].value,
>         prefill=prefill
>     )
> 
>     return return_value (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.operations:735
> ==taskenizer.functions.process_data:379
>     to_be_inserted = [
>         genid(cur_time),
>         form["data-category"].value,
>         color,
>         nom,
>         1, (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.operations:422
> ==taskenizer.functions.process_data:1064
>                             color,
>                             name,
>                             deferred,
>                             def_days,
>                             def_months,
>                             def_years, (duplicate-code)
> R:  1, 0: Similar lines in 4 files
> ==taskenizer.functions.display:228
> ==taskenizer.functions.display:277
> ==taskenizer.pages.main:192
> ==taskenizer.pages.manu_habits:59
>         conn.execute('''SELECT COUNT(*)
>                      FROM CatKey
>                      WHERE task_type = ?
>                      AND user_id = ?;''', tup)
>         num_cats = conn.fetchone()
>  (duplicate-code)
> R:  1, 0: Similar lines in 3 files
> ==taskenizer.functions.process_data:1600
> ==taskenizer.functions.process_data:1645
> ==taskenizer.pages.configuration:234
>                      FROM PageContent
>                      WHERE page_id = ?
>                      AND user_id = ?
>                      ORDER BY seq;""", tup)
>         contents = conn.fetchall()
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.pages.landing:27
> ==taskenizer.pages.register:29
>         css_code=css_code,
>         ua=environ['HTTP_USER_AGENT'],
>         root=conf['System']['taskenizer_static'],
>         engine=conf['System']['taskenizer_engine']
>     )
>  (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.task_funcs:459
> ==taskenizer.taskenizer:213
>                                                user_id,
>                                                cur_time,
>                                                expires,
>                                                ex_head
>                                                )
>  (duplicate-code)
> R:  1, 0: Similar lines in 3 files
> ==taskenizer.functions.operations:1008
> ==taskenizer.functions.operations:904
> ==taskenizer.functions.process_data:281
>                                  def_days = ?,
>                                  def_months = ?,
>                                  def_years = ?
>                                  WHERE id = ?;''', tup)
>                 except ValueError as error: (duplicate-code)
> R:  1, 0: Similar lines in 3 files
> ==taskenizer.functions.operations:895
> ==taskenizer.functions.operations:999
> ==taskenizer.functions.process_data:272
>                     tup = (
>                         nom,
>                         form["task-next-day_" + itnum].value,
>                         form["task-next-month_" + itnum].value,
>                         form["task-next-year_" + itnum].value, (duplicate-code)
> R:  1, 0: Similar lines in 3 files
> ==taskenizer.functions.operations:869
> ==taskenizer.functions.operations:973
> ==taskenizer.functions.process_data:242
>                 for key in form:
>                     if re.search('^dataid_', key):
>                         try:
>                             itnum = re.sub('_categ_.+', '',
>                                            re.sub('^dataid_', '', key)) (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.operations:613
> ==taskenizer.functions.process_data:1227
>                                         name,
>                                         freq,
>                                         freq_units,
>                                         due_days,
>                                         due_months, (duplicate-code)
> R:  1, 0: Similar lines in 2 files
> ==taskenizer.functions.display:30
> ==taskenizer.pages.configuration:220
>     tup = (user_id,)
>     conn.execute('''SELECT id, name
>                  FROM Page
>                  WHERE user_id = ?
>                  ORDER BY seq;''', tup) (duplicate-code)
> R:  1, 0: Similar lines in 5 files
> ==taskenizer.mini_pages.move_page:233
> ==taskenizer.mini_pages.move_page:249
> ==taskenizer.mini_pages.move_page:265
> ==taskenizer.pages.auto_habits:33
> ==taskenizer.pages.manu_habits:33
>     conn.execute('''SELECT cat_id
>                  FROM CatKey
>                  WHERE task_type = ?
>                  AND user_id = ?
>                  ORDER BY id ASC;''', tup) (duplicate-code)
338c1122
<       \-fernet (taskenizer.functions.crypto)
---
>       \-fernet (taskenizer.functions.crypto,taskenizer.functions.operations)
340c1124
<         \-backends (taskenizer.functions.crypto)
---
>         \-backends (taskenizer.functions.crypto,taskenizer.functions.operations,taskenizer.functions.task_funcs,taskenizer.mini_pages.ac_deletion,taskenizer.mini_pages.del_other,taskenizer.mini_pages.modify_pass,taskenizer.mini_pages.modify_username,taskenizer.mini_pages.share_cat)
342,345c1126,1129
<           \-ciphers (taskenizer.functions.crypto)
<           | \-algorithms (taskenizer.functions.crypto)
<           | \-modes (taskenizer.functions.crypto)
<           \-hashes (taskenizer.functions.task_funcs)
---
>           \-ciphers (taskenizer.functions.crypto,taskenizer.functions.operations,taskenizer.functions.task_funcs,taskenizer.mini_pages.modify_pass,taskenizer.mini_pages.share_cat)
>           | \-algorithms (taskenizer.functions.crypto,taskenizer.functions.operations,taskenizer.functions.task_funcs,taskenizer.mini_pages.modify_pass,taskenizer.mini_pages.share_cat)
>           | \-modes (taskenizer.functions.crypto,taskenizer.functions.operations,taskenizer.functions.task_funcs,taskenizer.mini_pages.modify_pass,taskenizer.mini_pages.share_cat)
>           \-hashes (taskenizer.functions.operations,taskenizer.functions.task_funcs,taskenizer.mini_pages.ac_deletion,taskenizer.mini_pages.del_other,taskenizer.mini_pages.modify_pass,taskenizer.mini_pages.modify_username,taskenizer.mini_pages.share_cat)
347c1131
<             \-pbkdf2 (taskenizer.functions.task_funcs)
---
>             \-pbkdf2 (taskenizer.functions.operations,taskenizer.functions.task_funcs,taskenizer.mini_pages.ac_deletion,taskenizer.mini_pages.del_other,taskenizer.mini_pages.modify_pass,taskenizer.mini_pages.modify_username,taskenizer.mini_pages.share_cat)
350,351c1134,1135
<     jinja2 (taskenizer.functions.task_funcs)
<     pytz (taskenizer.functions.process_data)
---
>     jinja2 (taskenizer.functions.task_funcs,taskenizer.pages.biscuits)
>     pytz (taskenizer.functions.operations,taskenizer.functions.process_data,taskenizer.pages.configuration,taskenizer.pages.register)
354,356c1138,1141
<       | \-crypto (taskenizer.functions.process_data)
<       | \-display (taskenizer.functions.process_data)
<       | \-operations (taskenizer.functions.process_data)
---
>       | \-crypto (taskenizer.functions.display,taskenizer.functions.operations,taskenizer.functions.process_data,taskenizer.mini_pages.defer_task_page,taskenizer.mini_pages.modify_auto_habit_page,taskenizer.mini_pages.modify_biscuit_page,taskenizer.mini_pages.modify_manu_habit_page,taskenizer.mini_pages.modify_note_page,taskenizer.mini_pages.move_page,taskenizer.pages.auto_habits,taskenizer.pages.biscuits,taskenizer.pages.deferred_tasks,taskenizer.pages.main,taskenizer.pages.manu_habits)
>       | \-display (taskenizer.functions.process_data,taskenizer.functions.task_funcs,taskenizer.mini_pages.ac_deletion,taskenizer.mini_pages.add_auto_habit_page,taskenizer.mini_pages.add_deferred_note_page,taskenizer.mini_pages.add_manu_habit_page,taskenizer.mini_pages.defer_task_page,taskenizer.mini_pages.del_other,taskenizer.mini_pages.modify_auto_habit_page,taskenizer.mini_pages.modify_biscuit_page,taskenizer.mini_pages.modify_manu_habit_page,taskenizer.mini_pages.modify_note_page,taskenizer.mini_pages.modify_pass,taskenizer.mini_pages.modify_username,taskenizer.mini_pages.move_page,taskenizer.mini_pages.share_cat,taskenizer.pages.auto_habits,taskenizer.pages.biscuits,taskenizer.pages.configuration,taskenizer.pages.deferred_tasks,taskenizer.pages.landing,taskenizer.pages.main,taskenizer.pages.manu_habits,taskenizer.pages.register)
>       | \-operations (taskenizer.functions.display,taskenizer.functions.process_data,taskenizer.functions.task_funcs,taskenizer.mini_pages.add_auto_habit_page,taskenizer.mini_pages.add_deferred_note_page,taskenizer.mini_pages.add_manu_habit_page,taskenizer.mini_pages.defer_task_page,taskenizer.mini_pages.modify_auto_habit_page,taskenizer.mini_pages.modify_manu_habit_page,taskenizer.mini_pages.modify_note_page,taskenizer.mini_pages.move_page,taskenizer.mini_pages.share_cat,taskenizer.pages.deferred_tasks,taskenizer.pages.main,taskenizer.pages.register,taskenizer.taskenizer)
>       | \-process_data (taskenizer.functions.task_funcs)
391c1176
< |code      |5301   |61.22 |5301     |=          |
---
> |code      |5301   |61.22 |5296     |+5.00      |
397c1182
< |empty     |1656   |19.12 |1656     |=          |
---
> |empty     |1656   |19.12 |1651     |+5.00      |
405,411c1190,1196
< +-------------------------+------+---------+-----------+
< |                         |now   |previous |difference |
< +=========================+======+=========+===========+
< |nb duplicated lines      |0     |0        |=          |
< +-------------------------+------+---------+-----------+
< |percent duplicated lines |0.000 |0.000    |=          |
< +-------------------------+------+---------+-----------+
---
> +-------------------------+-------+---------+-----------+
> |                         |now    |previous |difference |
> +=========================+=======+=========+===========+
> |nb duplicated lines      |984    |984      |=          |
> +-------------------------+-------+---------+-----------+
> |percent duplicated lines |11.787 |11.801   |-0.01      |
> +-------------------------+-------+---------+-----------+
421c1206
< |convention |105    |105      |=          |
---
> |convention |105    |103      |+2.00      |
423c1208
< |refactor   |143    |143      |=          |
---
> |refactor   |198    |188      |+10.00     |
425c1210
< |warning    |33     |33       |=          |
---
> |warning    |33     |32       |+1.00      |
438c1223
< |taskenizer.functions.task_funcs              |0.00  |48.48   |7.69     |9.52       |
---
> |taskenizer.functions.task_funcs              |0.00  |48.48   |5.56     |9.52       |
440c1225
< |taskenizer.functions.operations              |0.00  |27.27   |25.87    |13.33      |
---
> |taskenizer.functions.operations              |0.00  |27.27   |18.69    |13.33      |
442c1227
< |taskenizer.functions.process_data            |0.00  |15.15   |13.99    |4.76       |
---
> |taskenizer.functions.process_data            |0.00  |15.15   |10.10    |4.76       |
444c1229
< |taskenizer.functions.display                 |0.00  |3.03    |9.09     |9.52       |
---
> |taskenizer.functions.display                 |0.00  |3.03    |6.57     |9.52       |
446c1231
< |taskenizer.taskenizer                        |0.00  |3.03    |2.10     |12.38      |
---
> |taskenizer.taskenizer                        |0.00  |3.03    |1.52     |12.38      |
448c1233
< |taskenizer.pages.auto_habits                 |0.00  |3.03    |1.40     |1.90       |
---
> |taskenizer.pages.auto_habits                 |0.00  |3.03    |1.01     |1.90       |
450c1235
< |taskenizer.pages.deferred_tasks              |0.00  |0.00    |3.50     |1.90       |
---
> |taskenizer.functions.__init__                |0.00  |0.00    |27.78    |0.00       |
452c1237
< |taskenizer.mini_pages.share_cat              |0.00  |0.00    |2.80     |2.86       |
---
> |taskenizer.pages.deferred_tasks              |0.00  |0.00    |2.53     |1.90       |
454c1239
< |taskenizer.mini_pages.move_page              |0.00  |0.00    |2.80     |1.90       |
---
> |taskenizer.mini_pages.share_cat              |0.00  |0.00    |2.02     |2.86       |
456c1241
< |taskenizer.mini_pages.modify_note_page       |0.00  |0.00    |2.80     |1.90       |
---
> |taskenizer.mini_pages.move_page              |0.00  |0.00    |2.02     |1.90       |
458c1243
< |taskenizer.mini_pages.defer_task_page        |0.00  |0.00    |2.80     |1.90       |
---
> |taskenizer.mini_pages.modify_note_page       |0.00  |0.00    |2.02     |1.90       |
460c1245
< |taskenizer.pages.configuration               |0.00  |0.00    |2.10     |2.86       |
---
> |taskenizer.mini_pages.defer_task_page        |0.00  |0.00    |2.02     |1.90       |
462c1247
< |taskenizer.pages.main                        |0.00  |0.00    |2.10     |1.90       |
---
> |taskenizer.pages.configuration               |0.00  |0.00    |1.52     |2.86       |
464c1249
< |taskenizer.mini_pages.modify_pass            |0.00  |0.00    |2.10     |1.90       |
---
> |taskenizer.pages.main                        |0.00  |0.00    |1.52     |1.90       |
466c1251
< |taskenizer.functions.crypto                  |0.00  |0.00    |1.40     |4.76       |
---
> |taskenizer.mini_pages.modify_pass            |0.00  |0.00    |1.52     |1.90       |
468c1253
< |taskenizer.pages.register                    |0.00  |0.00    |1.40     |2.86       |
---
> |taskenizer.functions.crypto                  |0.00  |0.00    |1.01     |4.76       |
470c1255
< |taskenizer.mini_pages.ac_deletion            |0.00  |0.00    |1.40     |2.86       |
---
> |taskenizer.pages.register                    |0.00  |0.00    |1.01     |2.86       |
472c1257
< |taskenizer.pages.manu_habits                 |0.00  |0.00    |1.40     |1.90       |
---
> |taskenizer.mini_pages.ac_deletion            |0.00  |0.00    |1.01     |2.86       |
474c1259
< |taskenizer.pages.biscuits                    |0.00  |0.00    |1.40     |1.90       |
---
> |taskenizer.pages.manu_habits                 |0.00  |0.00    |1.01     |1.90       |
476c1261
< |taskenizer.mini_pages.modify_username        |0.00  |0.00    |1.40     |1.90       |
---
> |taskenizer.pages.biscuits                    |0.00  |0.00    |1.01     |1.90       |
478c1263
< |taskenizer.mini_pages.modify_manu_habit_page |0.00  |0.00    |1.40     |1.90       |
---
> |taskenizer.mini_pages.modify_username        |0.00  |0.00    |1.01     |1.90       |
480c1265
< |taskenizer.mini_pages.modify_biscuit_page    |0.00  |0.00    |1.40     |1.90       |
---
> |taskenizer.mini_pages.modify_manu_habit_page |0.00  |0.00    |1.01     |1.90       |
482c1267
< |taskenizer.mini_pages.modify_auto_habit_page |0.00  |0.00    |1.40     |1.90       |
---
> |taskenizer.mini_pages.modify_biscuit_page    |0.00  |0.00    |1.01     |1.90       |
484c1269
< |taskenizer.mini_pages.del_other              |0.00  |0.00    |1.40     |1.90       |
---
> |taskenizer.mini_pages.modify_auto_habit_page |0.00  |0.00    |1.01     |1.90       |
486c1271
< |taskenizer.mini_pages.add_manu_habit_page    |0.00  |0.00    |1.40     |1.90       |
---
> |taskenizer.mini_pages.del_other              |0.00  |0.00    |1.01     |1.90       |
488c1273
< |taskenizer.mini_pages.add_deferred_note_page |0.00  |0.00    |1.40     |1.90       |
---
> |taskenizer.mini_pages.add_manu_habit_page    |0.00  |0.00    |1.01     |1.90       |
490c1275
< |taskenizer.mini_pages.add_auto_habit_page    |0.00  |0.00    |1.40     |1.90       |
---
> |taskenizer.mini_pages.add_deferred_note_page |0.00  |0.00    |1.01     |1.90       |
492c1277,1279
< |taskenizer.pages.landing                     |0.00  |0.00    |0.70     |1.90       |
---
> |taskenizer.mini_pages.add_auto_habit_page    |0.00  |0.00    |1.01     |1.90       |
> +---------------------------------------------+------+--------+---------+-----------+
> |taskenizer.pages.landing                     |0.00  |0.00    |0.51     |1.90       |
504a1292,1293
> |duplicate-code             |55          |
> +---------------------------+------------+
550c1339
< Your code has been rated at 9.13/10 (previous run: 9.13/10, +0.00)
---
> Your code has been rated at 8.96/10 (previous run: 9.00/10, -0.04)

@mjbogusz
Copy link

I've encountered that too.

To properly detect duplicate code, pylint must be run with --jobs=1 - for me this caused CI jobs to fail whereas seemingly the same command with the same environment succeeded on a development machine, difference being 1 core available on the CI server and 4 on the dev machine.

I've verified this by saving the following script as 2 duplicate files, test1.py and test2.py:

import os
import sys

def main():
	print('test')
	print(sys.argv)
	print(os.environ)
	sys.exit(1)

if __name__ == '__main__':
	main()

and running:

pylint --jobs=2 test1.py test2.py
pylint --jobs=1 test1.py test2.py

Only the second command reported duplicate code.

@Pierre-Sassoulas
Copy link
Member

Closing because it's a duplicate of #3314 that was fixed in #4007

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
5 participants