nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: mholt/PapaParse
Pull request #503 (2018-05-05 02:09:41)

When guessing a delimiter, lines with comments are ignored now
This PR addresses the issue: "Skip comments for delimiter detection #489".

The guessDelimiter function now takes the comments config and that seems to fix the problem of it failing when there are 10 or more lines of comments at the beginning of CSV.


Patch:
diff --git a/papaparse.js b/papaparse.js
index b7fa8db..fa8611d 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -898,7 +898,7 @@
 			_delimiterError = false;
 			if (!_config.delimiter)
 			{
-				var delimGuess = guessDelimiter(input, _config.newline, _config.skipEmptyLines);
+				var delimGuess = guessDelimiter(input, _config.newline, _config.skipEmptyLines, _config.comments);
 				if (delimGuess.successful)
 					_config.delimiter = delimGuess.bestDelimiter;
 				else
@@ -1073,7 +1073,7 @@
 			return _results;
 		}
 
-		function guessDelimiter(input, newline, skipEmptyLines)
+		function guessDelimiter(input, newline, skipEmptyLines, comments)
 		{
 			var delimChoices = [',', '\t', '|', ';', Papa.RECORD_SEP, Papa.UNIT_SEP];
 			var bestDelim, bestDelta, fieldCountPrevRow;
@@ -1085,6 +1085,7 @@
 				fieldCountPrevRow = undefined;
 
 				var preview = new Parser({
+					comments: comments,
 					delimiter: delim,
 					newline: newline,
 					preview: 10
@@ -1632,7 +1633,7 @@
 	/** Makes a deep copy of an array or object (mostly) */
 	function copy(obj)
 	{
-		if (typeof obj !== 'object')
+		if (typeof obj !== 'object' || obj === null)
 			return obj;
 		var cpy = obj instanceof Array ? [] : {};
 		for (var key in obj)


Test patch:
diff --git a/tests/test-cases.js b/tests/test-cases.js
index 773635e..b10c386 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -1090,6 +1090,26 @@ var PARSE_TESTS = [
 			errors: []
 		}
 	},
+	{
+		description: "Lines with comments are not used when guessing the delimiter in an escaped file",
+		notes: "Guessing the delimiter should work even if there are many lines of comments at the start of the file",
+		input: '#1\n#2\n#3\n#4\n#5\n#6\n#7\n#8\n#9\n#10\none,"t,w,o",three\nfour,five,six',
+		config: { comments: '#' },
+		expected: {
+			data: [['one','t,w,o','three'],['four','five','six']],
+			errors: []
+		}
+	},
+	{
+		description: "Lines with comments are not used when guessing the delimiter in a non-escaped file",
+		notes: "Guessing the delimiter should work even if there are many lines of comments at the start of the file",
+		input: '#1\n#2\n#3\n#4\n#5\n#6\n#7\n#8\n#9\n#10\n#11\none,two,three\nfour,five,six',
+		config: { comments: '#' },
+		expected: {
+			data: [['one','two','three'],['four','five','six']],
+			errors: []
+		}
+	},
 	{
 		description: "Single quote as quote character",
 		notes: "Must parse correctly when single quote is specified as a quote character",
Repository: mholt/PapaParse
Pull request #519 (2018-06-08 17:17:19)

Allow multi-characters delimiter at serialization.
Scope
=====

This updates the serialization code to allow multi-character delimiters.

I want to present the values in a more human readable format with `, ` as delimiter so that the lines will be `1, 2, 3` instead of `1,2,3`


Changes
========

Update the validation to not enforce single characters, but to still filter against invalid characters.

In this way there is no regression and all previous tests pass.

I added a new test to showcase this functionality

As a drive-by fix, I have updated the phantomjs test runner to propagate the exit code
as it was always exiting with 0 even on errors see https://travis-ci.org/mholt/PapaParse/jobs/389825011#L1418

----------

Once this is accepted the documentation needs to be updated at https://github.com/mholt/PapaParse/blob/gh-pages/docs.html#L256

to inform that it accepts multiple characters

Thanks for the nice library.

I hope you can accept this change. Let me know if you want anything done in another way.



adiroiban: I see that Travis-CI is happy but I now see that phantom fails with
``
TypeError: 'undefined' is not a function (evaluating '_config.delimiter.includes(value)')
```

Patch:
diff --git a/papaparse.js b/papaparse.js
index 8106e8d..5f670bd 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -271,7 +271,7 @@
 		/** whether to write headers */
 		var _writeHeader = true;
 
-		/** delimiting character */
+		/** delimiting character(s) */
 		var _delimiter = ',';
 
 		/** newline character(s) */
@@ -326,8 +326,7 @@
 				return;
 
 			if (typeof _config.delimiter === 'string'
-				&& _config.delimiter.length === 1
-				&& Papa.BAD_DELIMITERS.indexOf(_config.delimiter) === -1)
+                && !Papa.BAD_DELIMITERS.filter(function(value) { return _config.delimiter.indexOf(value) !== -1; }).length)
 			{
 				_delimiter = _config.delimiter;
 			}


Test patch:
diff --git a/tests/test-cases.js b/tests/test-cases.js
index b7f55ef..ad0d9a5 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -1396,6 +1396,12 @@ var UNPARSE_TESTS = [
 		config: { delimiter: RECORD_SEP },
 		expected: 'a' + RECORD_SEP + 'b' + RECORD_SEP + 'c\r\nd' + RECORD_SEP + 'e' + RECORD_SEP + 'f'
 	},
+	{
+		description: "Custom delimiter (Multi-character)",
+		input: [['A', 'b', 'c'], ['d', 'e', 'f']],
+		config: { delimiter: ', ' },
+		expected: 'A, b, c\r\nd, e, f'
+	},
 	{
 		description: "Bad delimiter (\\n)",
 		notes: "Should default to comma",
diff --git a/tests/test.js b/tests/test.js
index 782d4a8..f4fed5f 100644
--- a/tests/test.js
+++ b/tests/test.js
@@ -8,8 +8,9 @@ var server = connect().use(serveStatic(path.join(__dirname, '/..'))).listen(8071
 	if (process.argv.indexOf('--phantomjs') !== -1) {
 		childProcess.spawn('node_modules/.bin/mocha-phantomjs', ['http://localhost:8071/tests/tests.html'], {
 			stdio: 'inherit'
-		}).on('exit', function() {
+		}).on('exit', function(code) {
 			server.close();
+			process.exit(code);  // eslint-disable-line no-process-exit
 		});
 
 	} else {
Repository: mholt/PapaParse
Pull request #696 (2019-07-28 08:51:48)

Bugfix: Resolve parsing issue when first field is empty and unquoted
This resolves the issue mentioned in #685 

thomasjulianstoelen: @dboskovic hey david just curious, how come we continue on as an empty string instead of throwing an error saying a header is missing?
dboskovic: There’s two layers here. One where we parse which should absolutely allow for anything in the RFC and be forgiving beyond. In this case empty data should never be a problem.

I think when you enable header mapping, we could introduce a strict mode that produces errors in the case of an empty header (or multiple identical headers) that could cause unexpected data in the end result. That said, I don’t think it’s unreasonable for there to be unlabeled columns in a dataset, so My gut says that type of validation would be better living downstream from this library.

Patch:
diff --git a/papaparse.js b/papaparse.js
index acf4c95..b64d201 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -1608,7 +1608,7 @@ License: MIT
 						var nextDelimObj = getNextUnqotedDelimiter(nextDelim, quoteSearch, nextNewline);
 
 						// if we have next delimiter char which is not enclosed in quotes
-						if (nextDelimObj && nextDelimObj.nextDelim) {
+						if (nextDelimObj && typeof nextDelimObj.nextDelim !== 'undefined') {
 							nextDelim = nextDelimObj.nextDelim;
 							quoteSearch = nextDelimObj.quoteSearch;
 							row.push(input.substring(cursor, nextDelim));


Test patch:
diff --git a/tests/test-cases.js b/tests/test-cases.js
index 81a2dce..45db0e6 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -323,6 +323,14 @@ var CORE_PARSER_TESTS = [
 			errors: []
 		}
 	},
+	{
+		description: "Line starts with unquoted empty field",
+		input: ',b,c\n"d",e,f',
+		expected: {
+			data: [['', 'b', 'c'], ['d', 'e', 'f']],
+			errors: []
+		}
+	},
 	{
 		description: "Line ends with quoted field",
 		input: 'a,b,c\nd,e,f\n"g","h","i"\n"j","k","l"',
Repository: mholt/PapaParse
Pull request #702 (2019-08-24 18:41:28)

Fix  misplaced quotes parsing (#699)
This is a fix for #699 


Patch:
diff --git a/papaparse.js b/papaparse.js
index 7658de0..b1cb416 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -1603,7 +1603,7 @@ License: MIT
 				if (nextDelim !== -1 && (nextDelim < nextNewline || nextNewline === -1))
 				{
 					// we check, if we have quotes, because delimiter char may be part of field enclosed in quotes
-					if (quoteSearch !== -1) {
+					if (quoteSearch > nextDelim) {
 						// we have quotes, so we try to find the next delimiter not enclosed in quotes and also next starting quote char
 						var nextDelimObj = getNextUnqotedDelimiter(nextDelim, quoteSearch, nextNewline);
 


Test patch:
diff --git a/tests/test-cases.js b/tests/test-cases.js
index 45db0e6..dadb724 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -670,6 +670,14 @@ var PARSE_TESTS = [
 			errors: []
 		}
 	},
+	{
+		description: "Misplaced quotes in data twice, not as opening quotes",
+		input: 'A,B",C\nD,E",F',
+		expected: {
+			data: [['A', 'B"', 'C'], ['D', 'E"', 'F']],
+			errors: []
+		}
+	},
 	{
 		description: "Mixed slash n and slash r should choose first as precident",
 		input: 'a,b,c\nd,e,f\rg,h,i\n',
Repository: mholt/PapaParse
Pull request #714 (2019-10-06 10:42:49)

Fix step callback function when skipping empty lines (#672)
Fixes https://github.com/mholt/PapaParse/issues/672#issuecomment-522758754


Patch:
diff --git a/package.json b/package.json
index 4769a19..b0d5bce 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
 		"grunt-contrib-uglify": "^3.3.0",
 		"mocha": "^5.2.0",
 		"mocha-headless-chrome": "^2.0.1",
-		"open": "0.0.5",
+		"open": "7.0.0",
 		"serve-static": "^1.7.1"
 	},
 	"scripts": {
diff --git a/papaparse.js b/papaparse.js
index b624e50..f1674f5 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -1036,8 +1036,10 @@ License: MIT
 					_stepCounter += results.data.length;
 					if (_config.preview && _stepCounter > _config.preview)
 						_parser.abort();
-					else
+					else {
+						_results.data = _results.data[0];
 						userStep(_results, self);
+					}
 				}
 			};
 		}
@@ -1706,11 +1708,10 @@ License: MIT
 			}
 
 			/** Returns an object with the results, errors, and meta. */
-			function returnable(stopped, step)
+			function returnable(stopped)
 			{
-				var isStep = step || false;
 				return {
-					data: isStep ? data[0]  : data,
+					data: data,
 					errors: errors,
 					meta: {
 						delimiter: delim,
@@ -1725,7 +1726,7 @@ License: MIT
 			/** Executes the user's step function and resets data & errors. */
 			function doStep()
 			{
-				step(returnable(undefined, true));
+				step(returnable());
 				data = [];
 				errors = [];
 			}


Test patch:
diff --git a/tests/test-cases.js b/tests/test-cases.js
index 0c4ab04..58a85f0 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -1973,6 +1973,22 @@ var CUSTOM_TESTS = [
 			});
 		}
 	},
+	{
+		description: "Data is correctly parsed with steps when skipping empty lines",
+		expected: [['A', 'b', 'c'], ['d', 'E', 'f']],
+		run: function(callback) {
+			var data = [];
+			Papa.parse('A,b,c\n\nd,E,f', {
+				skipEmptyLines: true,
+				step: function(results) {
+					data.push(results.data);
+				},
+				complete: function() {
+					callback(data);
+				}
+			});
+		}
+	},
 	{
 		description: "Step is called with the contents of the row",
 		expected: ['A', 'b', 'c'],
Repository: mholt/PapaParse
Pull request #872 (2021-05-27 16:17:26)

Update ISO_DATE regex to match full string
Fix issue #871 


Patch:
diff --git a/papaparse.js b/papaparse.js
index 26db15c..83ee4d0 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -1008,7 +1008,7 @@ License: MIT
 		var MAX_FLOAT = Math.pow(2, 53);
 		var MIN_FLOAT = -MAX_FLOAT;
 		var FLOAT = /^\s*-?(\d+\.?|\.\d+|\d+\.\d+)([eE][-+]?\d+)?\s*$/;
-		var ISO_DATE = /(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/;
+		var ISO_DATE = /^(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))$/;
 		var self = this;
 		var _stepCounter = 0;	// Number of times step was called (number of rows parsed)
 		var _rowCounter = 0;	// Number of rows that have been parsed so far


Test patch:
diff --git a/tests/test-cases.js b/tests/test-cases.js
index 8d15b29..d727bfe 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -997,6 +997,15 @@ var PARSE_TESTS = [
 			errors: []
 		}
 	},
+	{
+		description: "Dynamic typing skips ISO date strings ocurring in other strings",
+		input: 'ISO date,String with ISO date\r\n2018-05-04T21:08:03.269Z,The date is 2018-05-04T21:08:03.269Z\r\n2018-05-08T15:20:22.642Z,The date is 2018-05-08T15:20:22.642Z',
+		config: { dynamicTyping: true },
+		expected: {
+			data: [["ISO date", "String with ISO date"], [new Date("2018-05-04T21:08:03.269Z"), "The date is 2018-05-04T21:08:03.269Z"], [new Date("2018-05-08T15:20:22.642Z"), "The date is 2018-05-08T15:20:22.642Z"]],
+			errors: []
+		}
+	},
 	{
 		description: "Blank line at beginning",
 		input: '\r\na,b,c\r\nd,e,f',
Repository: mholt/PapaParse
Pull request #961 (2022-11-23 15:42:19)

Handle parsing utf-8 bom encoded files
Strip a character that's added in utf-8 BOM encoded files, fixing parsing issues. 

Fixes: https://github.com/mholt/PapaParse/issues/840
Possibly also fixes: https://github.com/mholt/PapaParse/issues/917


Patch:
diff --git a/papaparse.js b/papaparse.js
index 6c52906..f5a1f8f 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -235,6 +235,7 @@ License: MIT
 		}
 		else if (typeof _input === 'string')
 		{
+			_input = stripBom(_input);
 			if (_config.download)
 				streamer = new NetworkStreamer(_config);
 			else
@@ -248,6 +249,14 @@ License: MIT
 			streamer = new FileStreamer(_config);
 
 		return streamer.stream(_input);
+
+		// Strip character from UTF-8 BOM encoded files that cause issue parsing the file
+		function stripBom(string) {
+			if (string.charCodeAt(0) === 0xfeff) {
+				return string.slice(1);
+			}
+			return string;
+		}
 	}
 
 


Test patch:
diff --git a/tests/node-tests.js b/tests/node-tests.js
index 9c57a22..6d012ec 100644
--- a/tests/node-tests.js
+++ b/tests/node-tests.js
@@ -5,6 +5,7 @@ var Papa = require("../papaparse.js");
 var fs = require('fs');
 var assert = require('assert');
 var longSampleRawCsv = fs.readFileSync(__dirname + '/long-sample.csv', 'utf8');
+var utf8BomSampleRawCsv = fs.readFileSync(__dirname + '/utf-8-bom-sample.csv', 'utf8');
 
 function assertLongSampleParsedCorrectly(parsedCsv) {
 	assert.equal(8, parsedCsv.data.length);
@@ -287,4 +288,14 @@ describe('PapaParse', function() {
 			}
 		});
 	});
+
+	it('handles utf-8 BOM encoded files', function(done) {
+		Papa.parse(utf8BomSampleRawCsv, {
+			header: true,
+			complete: function(parsedCsv) {
+				assert.deepEqual(parsedCsv.data[0], { A: 'X', B: 'Y', C: 'Z' });
+				done();
+			}
+		});
+	});
 });
diff --git a/tests/utf-8-bom-sample.csv b/tests/utf-8-bom-sample.csv
new file mode 100644
index 0000000..4f85ff0
--- /dev/null
+++ b/tests/utf-8-bom-sample.csv
@@ -0,0 +1,2 @@
+﻿A,B,C
+X,Y,Z
Repository: mholt/PapaParse
Pull request #997 (2023-04-12 16:51:42)

Fixed cursor when duplicated header
When processing duplicate headers with header auto, the position of meta.cursor will be returned as the position of cursor including renamed headers such as _<number>. But it's different from the cursor of the actual file. So set the cursor to the length of the original header.


Patch:
diff --git a/papaparse.js b/papaparse.js
index 9071e6b..3ce3962 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -1469,9 +1469,10 @@ License: MIT
 				return returnable();
 
 			// Rename headers if there are duplicates
+			var firstLine;
 			if (config.header && !baseIndex)
 			{
-				var firstLine = input.split(newline)[0];
+				firstLine = input.split(newline)[0];
 				var headers = firstLine.split(delim);
 				var separator = '_';
 				var headerMap = new Set();
@@ -1516,7 +1517,12 @@ License: MIT
 				for (var i = 0; i < rows.length; i++)
 				{
 					row = rows[i];
-					cursor += row.length;
+					// use firstline as row length may be changed due to duplicated headers
+					if (i === 0 && firstLine !== undefined) {
+						cursor += firstLine.length;
+					}else{
+						cursor += row.length;
+					}
 					if (i !== rows.length - 1)
 						cursor += newline.length;
 					else if (ignoreLastRow)


Test patch:
diff --git a/tests/test-cases.js b/tests/test-cases.js
index 1bccea6..da489e8 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -594,7 +594,10 @@ var CORE_PARSER_TESTS = [
 		expected: {
 			data: [['A', 'A_1', 'A_2', 'A_3'], ['1', '2', '3', '4']],
 			errors: [],
-			meta: {renamedHeaders: {A_1: 'A', A_2: 'A', A_3: 'A'}}
+			meta: {
+				renamedHeaders: {A_1: 'A', A_2: 'A', A_3: 'A'},
+				cursor: 15
+			}
 		}
 	},
 	{
@@ -604,7 +607,10 @@ var CORE_PARSER_TESTS = [
 		expected: {
 			data: [['a', 'a_1', 'a_2', 'a_3'], ['1', '2', '3', '4']],
 			errors: [],
-			meta: {renamedHeaders: {a_1: 'a', a_2: 'a', a_3: 'a'}}
+			meta: {
+				renamedHeaders: {a_1: 'a', a_2: 'a', a_3: 'a'},
+				cursor: 15
+			}
 		}
 	},
 	{
@@ -614,7 +620,10 @@ var CORE_PARSER_TESTS = [
 		expected: {
 			data: [['c', 'c_1', 'c_2', 'c_1_0'], ['1', '2', '3', '4']],
 			errors: [],
-			meta: {renamedHeaders: {c_1: 'c', c_2: 'c'}}
+			meta: {
+				renamedHeaders: {c_1: 'c', c_2: 'c'},
+				cursor: 17
+			}
 		}
 	},
 ];
Repository: osmlab/maproulette3
Pull request #1267 (2020-06-10 00:38:43)

Handle user avatar url that is empty string


Patch:
diff --git a/src/interactions/User/AsAvatarUser.js b/src/interactions/User/AsAvatarUser.js
index 1b8bdaad..bb4f2036 100644
--- a/src/interactions/User/AsAvatarUser.js
+++ b/src/interactions/User/AsAvatarUser.js
@@ -1,4 +1,5 @@
 import _get from 'lodash/get'
+import _isEmpty from 'lodash/isEmpty'
 import defaultPic from '../../static/images/user_no_image.png'
 
 /**
@@ -14,9 +15,13 @@ export class AsAvatarUser {
   }
 
   profilePic(size) {
-    const urlParts = this.rawAvatarURL().replace(/\?s=\d+/, '?').split('?')
-    return /user_no_image/.test(this.rawAvatarURL()) ? defaultPic :
-           `${urlParts[0]}?s=${size}&${urlParts.slice(1).join('?')}`
+    const rawURL = this.rawAvatarURL()
+    if (_isEmpty(rawURL) || /user_no_image/.test(rawURL)) {
+      return defaultPic
+    }
+
+    const urlParts = rawURL.replace(/\?s=\d+/, '?').split('?')
+    return `${urlParts[0]}?s=${size}&${urlParts.slice(1).join('?')}`
   }
 }
 


Test patch:
diff --git a/src/interactions/User/AsAvatarUser.test.js b/src/interactions/User/AsAvatarUser.test.js
new file mode 100644
index 00000000..28ba1402
--- /dev/null
+++ b/src/interactions/User/AsAvatarUser.test.js
@@ -0,0 +1,14 @@
+import AsAvatarUser from './AsAvatarUser'
+import defaultPic from '../../static/images/user_no_image.png'
+
+describe('profilePic', () => {
+  it("returns default pic if user has empty avatar URL", () => {
+    const user = AsAvatarUser({avatarURL: ""})
+    expect(user.profilePic(200)).toEqual(defaultPic)
+  })
+
+  it("returns default pic if server is assigned default user_no_image avatar", () => {
+    const user = AsAvatarUser({avatarURL: "https://maproulette.org/images/user_no_image.jpg"})
+    expect(user.profilePic(200)).toEqual(defaultPic)
+  })
+})
Repository: conan-io/conan
Pull request #11449 (2022-06-13 16:44:24)

Allow ["ANY"] in a list 
Changelog: Feature: Allow options having ["ANY"] as a list like Conan 2.X.
Docs: https://github.com/conan-io/docs/pull/XXXX



Patch:
diff --git a/conans/model/options.py b/conans/model/options.py
index 5967e50b2..1b29d8957 100644
--- a/conans/model/options.py
+++ b/conans/model/options.py
@@ -331,7 +331,8 @@ class PackageOption(object):
     def __init__(self, possible_values, name):
         self._name = name
         self._value = None
-        if possible_values == "ANY":
+        if possible_values == "ANY" or (isinstance(possible_values, list) and
+                                        "ANY" in possible_values):
             self._possible_values = "ANY"
         else:
             self._possible_values = sorted(str(v) for v in possible_values)


Test patch:
diff --git a/conans/test/unittests/model/options_test.py b/conans/test/unittests/model/options_test.py
index 7bb1a8ef0..4d5a1db40 100644
--- a/conans/test/unittests/model/options_test.py
+++ b/conans/test/unittests/model/options_test.py
@@ -376,3 +376,21 @@ class OptionsValuesTest(unittest.TestCase):
     def test_package_with_spaces(self):
         self.assertEqual(OptionsValues([('pck2:opt', 50), ]).dumps(),
                          OptionsValues([('pck2 :opt', 50), ]).dumps())
+
+
+def test_validate_any_as_list():
+    package_options = PackageOptions.loads("""{
+    path: ["ANY", "kk"]}""")
+    values = PackageOptionValues()
+    values.add_option("path", "FOO")
+    package_options.values = values
+    sut = Options(package_options)
+    assert sut.path == "FOO"
+
+    package_options = PackageOptions.loads("""{
+        path: "ANY"}""")
+    values = PackageOptionValues()
+    values.add_option("path", "WHATEVER")
+    package_options.values = values
+    sut = Options(package_options)
+    assert sut.path == "WHATEVER"
Repository: conan-io/conan
Pull request #11968 (2022-08-26 17:24:58)

add targets to MSBuild
Changelog:  Feature: Add ``MSBuild().build(.., targets=["target1"])`` argument to new ``MSBuild``
Docs: https://github.com/conan-io/docs/pull/XXXX

Close https://github.com/conan-io/conan/issues/11966



Patch:
diff --git a/conan/tools/microsoft/msbuild.py b/conan/tools/microsoft/msbuild.py
index 287c46d72..e7a8df5fb 100644
--- a/conan/tools/microsoft/msbuild.py
+++ b/conan/tools/microsoft/msbuild.py
@@ -28,7 +28,7 @@ class MSBuild(object):
             msvc_arch = conanfile.settings.get_safe("os.platform")
         self.platform = msvc_arch
 
-    def command(self, sln):
+    def command(self, sln, targets=None):
         cmd = ('msbuild "%s" /p:Configuration=%s /p:Platform=%s'
                % (sln, self.build_type, self.platform))
 
@@ -41,10 +41,15 @@ class MSBuild(object):
         if maxcpucount:
             cmd += " /m:{}".format(maxcpucount)
 
+        if targets:
+            if not isinstance(targets, list):
+                raise ConanException("targets argument should be a list")
+            cmd += " /target:{}".format(";".join(targets))
+
         return cmd
 
-    def build(self, sln):
-        cmd = self.command(sln)
+    def build(self, sln, targets=None):
+        cmd = self.command(sln, targets=targets)
         self._conanfile.run(cmd)
 
     @staticmethod


Test patch:
diff --git a/conans/test/unittests/tools/microsoft/test_msbuild.py b/conans/test/unittests/tools/microsoft/test_msbuild.py
index 82bceeaf9..2311e5c0d 100644
--- a/conans/test/unittests/tools/microsoft/test_msbuild.py
+++ b/conans/test/unittests/tools/microsoft/test_msbuild.py
@@ -13,6 +13,23 @@ from conans.tools import load
 from conans import ConanFile, Settings
 
 
+def test_msbuild_targets():
+    c = ConfDefinition()
+    settings = MockSettings({"build_type": "Release",
+                             "compiler": "gcc",
+                             "compiler.version": "7",
+                             "os": "Linux",
+                             "arch": "x86_64"})
+    conanfile = ConanFileMock()
+    conanfile.settings = settings
+    conanfile.conf = c.get_conanfile_conf(None)
+
+    msbuild = MSBuild(conanfile)
+    cmd = msbuild.command('project.sln', targets=["static", "shared"])
+
+    assert '/target:static;shared' in cmd
+
+
 def test_msbuild_cpu_count():
     c = ConfDefinition()
     c.loads(textwrap.dedent("""\